Merge "Remove UntrustedChecker"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index ef7703e..04c5fcb 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -53,7 +53,7 @@
   luni/src/main/java \
   ojluni/src/main/resources/
 test_resource_dirs := $(call all-core-resource-dirs,test)
-test_src_files := $(call all-test-java-files-under,dalvik dom harmony-tests json luni xml)
+test_src_files := $(call all-test-java-files-under,dalvik dalvik/test-rules dom harmony-tests json luni xml)
 ojtest_src_files := $(call all-test-java-files-under,ojluni)
 
 ifeq ($(EMMA_INSTRUMENT),true)
@@ -166,6 +166,24 @@
 LOCAL_CORE_LIBRARY := true
 include $(BUILD_JAVA_LIBRARY)
 
+# Build libcore test rules for target
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-java-files-under, dalvik/test-rules/src/main test-rules/src/main)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_MODULE := core-test-rules
+LOCAL_JAVA_LIBRARIES := core-all core-junit
+LOCAL_STATIC_JAVA_LIBRARIES := junit4-target
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Build libcore test rules for host
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-java-files-under, dalvik/test-rules/src/main test-rules/src/main)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_MODULE := core-test-rules-hostdex
+LOCAL_JAVA_LIBRARIES := core-oj-hostdex core-libart-hostdex core-junit-hostdex
+LOCAL_STATIC_JAVA_LIBRARIES := junit4-target-hostdex
+include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(non_openjdk_java_files) $(android_icu4j_src_files)
 LOCAL_JAVA_RESOURCE_DIRS := $(android_icu4j_resource_dirs)
@@ -189,8 +207,14 @@
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp core-junit junit4-target bouncycastle mockito-target
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support sqlite-jdbc mockwebserver nist-pkix-tests
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	core-test-rules \
+	core-tests-support \
+	mockwebserver \
+	nist-pkix-tests \
+	sqlite-jdbc
 LOCAL_JAVACFLAGS := $(local_javac_flags)
+LOCAL_ERROR_PRONE_FLAGS := -Xep:TryFailThrowable:ERROR
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-tests
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
@@ -329,14 +353,14 @@
 LOCAL_CORE_LIBRARY := true
 include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 
-# Make the core-tests library.
+# Make the core-tests-hostdex library.
 ifeq ($(LIBCORE_SKIP_TESTS),)
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES := $(test_src_files)
     LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
     LOCAL_NO_STANDARD_LIBRARIES := true
     LOCAL_JAVA_LIBRARIES := core-oj-hostdex core-libart-hostdex okhttp-hostdex bouncycastle-hostdex core-junit-hostdex junit4-target-hostdex core-tests-support-hostdex mockito-api-hostdex
-    LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host
+    LOCAL_STATIC_JAVA_LIBRARIES := sqlite-jdbc-host mockwebserver-host nist-pkix-tests-host core-test-rules-hostdex
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_JAVA_LANGUAGE_VERSION := 1.8
@@ -416,6 +440,7 @@
  -title "libcore" \
  -proofread $(OUT_DOCS)/$(LOCAL_MODULE)-proofread.txt \
  -todo ../$(LOCAL_MODULE)-docs-todo.html \
+ -knowntags ./libcore/known_oj_tags.txt \
  -hdf android.whichdoc offline
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
diff --git a/NativeCode.mk b/NativeCode.mk
index 7c3efbc..85bd4a0 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -80,7 +80,7 @@
 core_shared_libraries := $(LOCAL_SHARED_LIBRARIES)
 core_static_libraries := $(LOCAL_STATIC_LIBRARIES)
 libart_cflags := $(LOCAL_CFLAGS) -Wall -Wextra -Werror
-core_cppflags += -std=gnu++11 -DU_USING_ICU_NAMESPACE=0
+core_cppflags += -DU_USING_ICU_NAMESPACE=0
 # TODO(narayan): Prune down this list of exclusions once the underlying
 # issues have been fixed. Most of these are small changes except for
 # -Wunused-parameter.
@@ -169,6 +169,7 @@
 LOCAL_C_INCLUDES += libcore/include
 LOCAL_SHARED_LIBRARIES += libnativehelper_compat_libc++
 LOCAL_MODULE_TAGS := optional
+LOCAL_STRIP_MODULE := keep_symbols
 LOCAL_MODULE := libjavacoretests
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/NativeCode.mk
 LOCAL_CXX_STL := libc++
diff --git a/benchmarks/src/benchmarks/CloneBenchmark.java b/benchmarks/src/benchmarks/CloneBenchmark.java
new file mode 100644
index 0000000..d05fb3d
--- /dev/null
+++ b/benchmarks/src/benchmarks/CloneBenchmark.java
@@ -0,0 +1,1071 @@
+/*
+ * Copyright (C) 2016 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;
+
+public class CloneBenchmark {
+    static class CloneableObject implements Cloneable {
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+    }
+
+    static class CloneableManyFieldObject implements Cloneable {
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+
+        Object o1 = new Object();
+        Object o2 = new Object();
+        Object o3 = new Object();
+        Object o4 = new Object();
+        Object o5 = new Object();
+        Object o6 = new Object();
+        Object o7 = new Object();
+        Object o8 = new Object();
+        Object o9 = new Object();
+        Object o10 = new Object();
+        Object o11 = new Object();
+        Object o12 = new Object();
+        Object o13 = new Object();
+        Object o14 = new Object();
+        Object o15 = new Object();
+        Object o16 = new Object();
+        Object o17 = new Object();
+        Object o18 = new Object();
+        Object o19 = new Object();
+        Object o20 = new Object();
+        Object o21 = new Object();
+        Object o22 = new Object();
+        Object o23 = new Object();
+        Object o24 = new Object();
+        Object o25 = new Object();
+        Object o26 = new Object();
+        Object o27 = new Object();
+        Object o28 = new Object();
+        Object o29 = new Object();
+        Object o30 = new Object();
+        Object o31 = new Object();
+        Object o32 = new Object();
+        Object o33 = new Object();
+        Object o34 = new Object();
+        Object o35 = new Object();
+        Object o36 = new Object();
+        Object o37 = new Object();
+        Object o38 = new Object();
+        Object o39 = new Object();
+        Object o40 = new Object();
+        Object o41 = new Object();
+        Object o42 = new Object();
+        Object o43 = new Object();
+        Object o44 = new Object();
+        Object o45 = new Object();
+        Object o46 = new Object();
+        Object o47 = new Object();
+        Object o48 = new Object();
+        Object o49 = new Object();
+        Object o50 = new Object();
+        Object o51 = new Object();
+        Object o52 = new Object();
+        Object o53 = new Object();
+        Object o54 = new Object();
+        Object o55 = new Object();
+        Object o56 = new Object();
+        Object o57 = new Object();
+        Object o58 = new Object();
+        Object o59 = new Object();
+        Object o60 = new Object();
+        Object o61 = new Object();
+        Object o62 = new Object();
+        Object o63 = new Object();
+        Object o64 = new Object();
+        Object o65 = new Object();
+        Object o66 = new Object();
+        Object o67 = new Object();
+        Object o68 = new Object();
+        Object o69 = new Object();
+        Object o70 = new Object();
+        Object o71 = new Object();
+        Object o72 = new Object();
+        Object o73 = new Object();
+        Object o74 = new Object();
+        Object o75 = new Object();
+        Object o76 = new Object();
+        Object o77 = new Object();
+        Object o78 = new Object();
+        Object o79 = new Object();
+        Object o80 = new Object();
+        Object o81 = new Object();
+        Object o82 = new Object();
+        Object o83 = new Object();
+        Object o84 = new Object();
+        Object o85 = new Object();
+        Object o86 = new Object();
+        Object o87 = new Object();
+        Object o88 = new Object();
+        Object o89 = new Object();
+        Object o90 = new Object();
+        Object o91 = new Object();
+        Object o92 = new Object();
+        Object o93 = new Object();
+        Object o94 = new Object();
+        Object o95 = new Object();
+        Object o96 = new Object();
+        Object o97 = new Object();
+        Object o98 = new Object();
+        Object o99 = new Object();
+        Object o100 = new Object();
+        Object o101 = new Object();
+        Object o102 = new Object();
+        Object o103 = new Object();
+        Object o104 = new Object();
+        Object o105 = new Object();
+        Object o106 = new Object();
+        Object o107 = new Object();
+        Object o108 = new Object();
+        Object o109 = new Object();
+        Object o110 = new Object();
+        Object o111 = new Object();
+        Object o112 = new Object();
+        Object o113 = new Object();
+        Object o114 = new Object();
+        Object o115 = new Object();
+        Object o116 = new Object();
+        Object o117 = new Object();
+        Object o118 = new Object();
+        Object o119 = new Object();
+        Object o120 = new Object();
+        Object o121 = new Object();
+        Object o122 = new Object();
+        Object o123 = new Object();
+        Object o124 = new Object();
+        Object o125 = new Object();
+        Object o126 = new Object();
+        Object o127 = new Object();
+        Object o128 = new Object();
+        Object o129 = new Object();
+        Object o130 = new Object();
+        Object o131 = new Object();
+        Object o132 = new Object();
+        Object o133 = new Object();
+        Object o134 = new Object();
+        Object o135 = new Object();
+        Object o136 = new Object();
+        Object o137 = new Object();
+        Object o138 = new Object();
+        Object o139 = new Object();
+        Object o140 = new Object();
+        Object o141 = new Object();
+        Object o142 = new Object();
+        Object o143 = new Object();
+        Object o144 = new Object();
+        Object o145 = new Object();
+        Object o146 = new Object();
+        Object o147 = new Object();
+        Object o148 = new Object();
+        Object o149 = new Object();
+        Object o150 = new Object();
+        Object o151 = new Object();
+        Object o152 = new Object();
+        Object o153 = new Object();
+        Object o154 = new Object();
+        Object o155 = new Object();
+        Object o156 = new Object();
+        Object o157 = new Object();
+        Object o158 = new Object();
+        Object o159 = new Object();
+        Object o160 = new Object();
+        Object o161 = new Object();
+        Object o162 = new Object();
+        Object o163 = new Object();
+        Object o164 = new Object();
+        Object o165 = new Object();
+        Object o166 = new Object();
+        Object o167 = new Object();
+        Object o168 = new Object();
+        Object o169 = new Object();
+        Object o170 = new Object();
+        Object o171 = new Object();
+        Object o172 = new Object();
+        Object o173 = new Object();
+        Object o174 = new Object();
+        Object o175 = new Object();
+        Object o176 = new Object();
+        Object o177 = new Object();
+        Object o178 = new Object();
+        Object o179 = new Object();
+        Object o180 = new Object();
+        Object o181 = new Object();
+        Object o182 = new Object();
+        Object o183 = new Object();
+        Object o184 = new Object();
+        Object o185 = new Object();
+        Object o186 = new Object();
+        Object o187 = new Object();
+        Object o188 = new Object();
+        Object o189 = new Object();
+        Object o190 = new Object();
+        Object o191 = new Object();
+        Object o192 = new Object();
+        Object o193 = new Object();
+        Object o194 = new Object();
+        Object o195 = new Object();
+        Object o196 = new Object();
+        Object o197 = new Object();
+        Object o198 = new Object();
+        Object o199 = new Object();
+        Object o200 = new Object();
+        Object o201 = new Object();
+        Object o202 = new Object();
+        Object o203 = new Object();
+        Object o204 = new Object();
+        Object o205 = new Object();
+        Object o206 = new Object();
+        Object o207 = new Object();
+        Object o208 = new Object();
+        Object o209 = new Object();
+        Object o210 = new Object();
+        Object o211 = new Object();
+        Object o212 = new Object();
+        Object o213 = new Object();
+        Object o214 = new Object();
+        Object o215 = new Object();
+        Object o216 = new Object();
+        Object o217 = new Object();
+        Object o218 = new Object();
+        Object o219 = new Object();
+        Object o220 = new Object();
+        Object o221 = new Object();
+        Object o222 = new Object();
+        Object o223 = new Object();
+        Object o224 = new Object();
+        Object o225 = new Object();
+        Object o226 = new Object();
+        Object o227 = new Object();
+        Object o228 = new Object();
+        Object o229 = new Object();
+        Object o230 = new Object();
+        Object o231 = new Object();
+        Object o232 = new Object();
+        Object o233 = new Object();
+        Object o234 = new Object();
+        Object o235 = new Object();
+        Object o236 = new Object();
+        Object o237 = new Object();
+        Object o238 = new Object();
+        Object o239 = new Object();
+        Object o240 = new Object();
+        Object o241 = new Object();
+        Object o242 = new Object();
+        Object o243 = new Object();
+        Object o244 = new Object();
+        Object o245 = new Object();
+        Object o246 = new Object();
+        Object o247 = new Object();
+        Object o248 = new Object();
+        Object o249 = new Object();
+        Object o250 = new Object();
+        Object o251 = new Object();
+        Object o252 = new Object();
+        Object o253 = new Object();
+        Object o254 = new Object();
+        Object o255 = new Object();
+        Object o256 = new Object();
+        Object o257 = new Object();
+        Object o258 = new Object();
+        Object o259 = new Object();
+        Object o260 = new Object();
+        Object o261 = new Object();
+        Object o262 = new Object();
+        Object o263 = new Object();
+        Object o264 = new Object();
+        Object o265 = new Object();
+        Object o266 = new Object();
+        Object o267 = new Object();
+        Object o268 = new Object();
+        Object o269 = new Object();
+        Object o270 = new Object();
+        Object o271 = new Object();
+        Object o272 = new Object();
+        Object o273 = new Object();
+        Object o274 = new Object();
+        Object o275 = new Object();
+        Object o276 = new Object();
+        Object o277 = new Object();
+        Object o278 = new Object();
+        Object o279 = new Object();
+        Object o280 = new Object();
+        Object o281 = new Object();
+        Object o282 = new Object();
+        Object o283 = new Object();
+        Object o284 = new Object();
+        Object o285 = new Object();
+        Object o286 = new Object();
+        Object o287 = new Object();
+        Object o288 = new Object();
+        Object o289 = new Object();
+        Object o290 = new Object();
+        Object o291 = new Object();
+        Object o292 = new Object();
+        Object o293 = new Object();
+        Object o294 = new Object();
+        Object o295 = new Object();
+        Object o296 = new Object();
+        Object o297 = new Object();
+        Object o298 = new Object();
+        Object o299 = new Object();
+        Object o300 = new Object();
+        Object o301 = new Object();
+        Object o302 = new Object();
+        Object o303 = new Object();
+        Object o304 = new Object();
+        Object o305 = new Object();
+        Object o306 = new Object();
+        Object o307 = new Object();
+        Object o308 = new Object();
+        Object o309 = new Object();
+        Object o310 = new Object();
+        Object o311 = new Object();
+        Object o312 = new Object();
+        Object o313 = new Object();
+        Object o314 = new Object();
+        Object o315 = new Object();
+        Object o316 = new Object();
+        Object o317 = new Object();
+        Object o318 = new Object();
+        Object o319 = new Object();
+        Object o320 = new Object();
+        Object o321 = new Object();
+        Object o322 = new Object();
+        Object o323 = new Object();
+        Object o324 = new Object();
+        Object o325 = new Object();
+        Object o326 = new Object();
+        Object o327 = new Object();
+        Object o328 = new Object();
+        Object o329 = new Object();
+        Object o330 = new Object();
+        Object o331 = new Object();
+        Object o332 = new Object();
+        Object o333 = new Object();
+        Object o334 = new Object();
+        Object o335 = new Object();
+        Object o336 = new Object();
+        Object o337 = new Object();
+        Object o338 = new Object();
+        Object o339 = new Object();
+        Object o340 = new Object();
+        Object o341 = new Object();
+        Object o342 = new Object();
+        Object o343 = new Object();
+        Object o344 = new Object();
+        Object o345 = new Object();
+        Object o346 = new Object();
+        Object o347 = new Object();
+        Object o348 = new Object();
+        Object o349 = new Object();
+        Object o350 = new Object();
+        Object o351 = new Object();
+        Object o352 = new Object();
+        Object o353 = new Object();
+        Object o354 = new Object();
+        Object o355 = new Object();
+        Object o356 = new Object();
+        Object o357 = new Object();
+        Object o358 = new Object();
+        Object o359 = new Object();
+        Object o360 = new Object();
+        Object o361 = new Object();
+        Object o362 = new Object();
+        Object o363 = new Object();
+        Object o364 = new Object();
+        Object o365 = new Object();
+        Object o366 = new Object();
+        Object o367 = new Object();
+        Object o368 = new Object();
+        Object o369 = new Object();
+        Object o370 = new Object();
+        Object o371 = new Object();
+        Object o372 = new Object();
+        Object o373 = new Object();
+        Object o374 = new Object();
+        Object o375 = new Object();
+        Object o376 = new Object();
+        Object o377 = new Object();
+        Object o378 = new Object();
+        Object o379 = new Object();
+        Object o380 = new Object();
+        Object o381 = new Object();
+        Object o382 = new Object();
+        Object o383 = new Object();
+        Object o384 = new Object();
+        Object o385 = new Object();
+        Object o386 = new Object();
+        Object o387 = new Object();
+        Object o388 = new Object();
+        Object o389 = new Object();
+        Object o390 = new Object();
+        Object o391 = new Object();
+        Object o392 = new Object();
+        Object o393 = new Object();
+        Object o394 = new Object();
+        Object o395 = new Object();
+        Object o396 = new Object();
+        Object o397 = new Object();
+        Object o398 = new Object();
+        Object o399 = new Object();
+        Object o400 = new Object();
+        Object o401 = new Object();
+        Object o402 = new Object();
+        Object o403 = new Object();
+        Object o404 = new Object();
+        Object o405 = new Object();
+        Object o406 = new Object();
+        Object o407 = new Object();
+        Object o408 = new Object();
+        Object o409 = new Object();
+        Object o410 = new Object();
+        Object o411 = new Object();
+        Object o412 = new Object();
+        Object o413 = new Object();
+        Object o414 = new Object();
+        Object o415 = new Object();
+        Object o416 = new Object();
+        Object o417 = new Object();
+        Object o418 = new Object();
+        Object o419 = new Object();
+        Object o420 = new Object();
+        Object o421 = new Object();
+        Object o422 = new Object();
+        Object o423 = new Object();
+        Object o424 = new Object();
+        Object o425 = new Object();
+        Object o426 = new Object();
+        Object o427 = new Object();
+        Object o428 = new Object();
+        Object o429 = new Object();
+        Object o430 = new Object();
+        Object o431 = new Object();
+        Object o432 = new Object();
+        Object o433 = new Object();
+        Object o434 = new Object();
+        Object o435 = new Object();
+        Object o436 = new Object();
+        Object o437 = new Object();
+        Object o438 = new Object();
+        Object o439 = new Object();
+        Object o440 = new Object();
+        Object o441 = new Object();
+        Object o442 = new Object();
+        Object o460 = new Object();
+        Object o461 = new Object();
+        Object o462 = new Object();
+        Object o463 = new Object();
+        Object o464 = new Object();
+        Object o465 = new Object();
+        Object o466 = new Object();
+        Object o467 = new Object();
+        Object o468 = new Object();
+        Object o469 = new Object();
+        Object o470 = new Object();
+        Object o471 = new Object();
+        Object o472 = new Object();
+        Object o473 = new Object();
+        Object o474 = new Object();
+        Object o475 = new Object();
+        Object o476 = new Object();
+        Object o477 = new Object();
+        Object o478 = new Object();
+        Object o479 = new Object();
+        Object o480 = new Object();
+        Object o481 = new Object();
+        Object o482 = new Object();
+        Object o483 = new Object();
+        Object o484 = new Object();
+        Object o485 = new Object();
+        Object o486 = new Object();
+        Object o487 = new Object();
+        Object o488 = new Object();
+        Object o489 = new Object();
+        Object o490 = new Object();
+        Object o491 = new Object();
+        Object o492 = new Object();
+        Object o493 = new Object();
+        Object o494 = new Object();
+        Object o495 = new Object();
+        Object o496 = new Object();
+        Object o497 = new Object();
+        Object o498 = new Object();
+        Object o499 = new Object();
+        Object o500 = new Object();
+        Object o501 = new Object();
+        Object o502 = new Object();
+        Object o503 = new Object();
+        Object o504 = new Object();
+        Object o505 = new Object();
+        Object o506 = new Object();
+        Object o507 = new Object();
+        Object o508 = new Object();
+        Object o509 = new Object();
+        Object o510 = new Object();
+        Object o511 = new Object();
+        Object o512 = new Object();
+        Object o513 = new Object();
+        Object o514 = new Object();
+        Object o515 = new Object();
+        Object o516 = new Object();
+        Object o517 = new Object();
+        Object o518 = new Object();
+        Object o519 = new Object();
+        Object o520 = new Object();
+        Object o521 = new Object();
+        Object o522 = new Object();
+        Object o523 = new Object();
+        Object o556 = new Object();
+        Object o557 = new Object();
+        Object o558 = new Object();
+        Object o559 = new Object();
+        Object o560 = new Object();
+        Object o561 = new Object();
+        Object o562 = new Object();
+        Object o563 = new Object();
+        Object o564 = new Object();
+        Object o565 = new Object();
+        Object o566 = new Object();
+        Object o567 = new Object();
+        Object o568 = new Object();
+        Object o569 = new Object();
+        Object o570 = new Object();
+        Object o571 = new Object();
+        Object o572 = new Object();
+        Object o573 = new Object();
+        Object o574 = new Object();
+        Object o575 = new Object();
+        Object o576 = new Object();
+        Object o577 = new Object();
+        Object o578 = new Object();
+        Object o579 = new Object();
+        Object o580 = new Object();
+        Object o581 = new Object();
+        Object o582 = new Object();
+        Object o583 = new Object();
+        Object o584 = new Object();
+        Object o585 = new Object();
+        Object o586 = new Object();
+        Object o587 = new Object();
+        Object o588 = new Object();
+        Object o589 = new Object();
+        Object o590 = new Object();
+        Object o591 = new Object();
+        Object o592 = new Object();
+        Object o593 = new Object();
+        Object o594 = new Object();
+        Object o595 = new Object();
+        Object o596 = new Object();
+        Object o597 = new Object();
+        Object o598 = new Object();
+        Object o599 = new Object();
+        Object o600 = new Object();
+        Object o601 = new Object();
+        Object o602 = new Object();
+        Object o603 = new Object();
+        Object o604 = new Object();
+        Object o605 = new Object();
+        Object o606 = new Object();
+        Object o607 = new Object();
+        Object o608 = new Object();
+        Object o609 = new Object();
+        Object o610 = new Object();
+        Object o611 = new Object();
+        Object o612 = new Object();
+        Object o613 = new Object();
+        Object o614 = new Object();
+        Object o615 = new Object();
+        Object o616 = new Object();
+        Object o617 = new Object();
+        Object o618 = new Object();
+        Object o619 = new Object();
+        Object o620 = new Object();
+        Object o621 = new Object();
+        Object o622 = new Object();
+        Object o623 = new Object();
+        Object o624 = new Object();
+        Object o625 = new Object();
+        Object o626 = new Object();
+        Object o627 = new Object();
+        Object o628 = new Object();
+        Object o629 = new Object();
+        Object o630 = new Object();
+        Object o631 = new Object();
+        Object o632 = new Object();
+        Object o633 = new Object();
+        Object o634 = new Object();
+        Object o635 = new Object();
+        Object o636 = new Object();
+        Object o637 = new Object();
+        Object o638 = new Object();
+        Object o639 = new Object();
+        Object o640 = new Object();
+        Object o641 = new Object();
+        Object o642 = new Object();
+        Object o643 = new Object();
+        Object o644 = new Object();
+        Object o645 = new Object();
+        Object o646 = new Object();
+        Object o647 = new Object();
+        Object o648 = new Object();
+        Object o649 = new Object();
+        Object o650 = new Object();
+        Object o651 = new Object();
+        Object o652 = new Object();
+        Object o653 = new Object();
+        Object o654 = new Object();
+        Object o655 = new Object();
+        Object o656 = new Object();
+        Object o657 = new Object();
+        Object o658 = new Object();
+        Object o659 = new Object();
+        Object o660 = new Object();
+        Object o661 = new Object();
+        Object o662 = new Object();
+        Object o663 = new Object();
+        Object o664 = new Object();
+        Object o665 = new Object();
+        Object o666 = new Object();
+        Object o667 = new Object();
+        Object o668 = new Object();
+        Object o669 = new Object();
+        Object o670 = new Object();
+        Object o671 = new Object();
+        Object o672 = new Object();
+        Object o673 = new Object();
+        Object o674 = new Object();
+        Object o675 = new Object();
+        Object o676 = new Object();
+        Object o677 = new Object();
+        Object o678 = new Object();
+        Object o679 = new Object();
+        Object o680 = new Object();
+        Object o681 = new Object();
+        Object o682 = new Object();
+        Object o683 = new Object();
+        Object o684 = new Object();
+        Object o685 = new Object();
+        Object o686 = new Object();
+        Object o687 = new Object();
+        Object o688 = new Object();
+        Object o734 = new Object();
+        Object o735 = new Object();
+        Object o736 = new Object();
+        Object o737 = new Object();
+        Object o738 = new Object();
+        Object o739 = new Object();
+        Object o740 = new Object();
+        Object o741 = new Object();
+        Object o742 = new Object();
+        Object o743 = new Object();
+        Object o744 = new Object();
+        Object o745 = new Object();
+        Object o746 = new Object();
+        Object o747 = new Object();
+        Object o748 = new Object();
+        Object o749 = new Object();
+        Object o750 = new Object();
+        Object o751 = new Object();
+        Object o752 = new Object();
+        Object o753 = new Object();
+        Object o754 = new Object();
+        Object o755 = new Object();
+        Object o756 = new Object();
+        Object o757 = new Object();
+        Object o758 = new Object();
+        Object o759 = new Object();
+        Object o760 = new Object();
+        Object o761 = new Object();
+        Object o762 = new Object();
+        Object o763 = new Object();
+        Object o764 = new Object();
+        Object o765 = new Object();
+        Object o766 = new Object();
+        Object o767 = new Object();
+        Object o768 = new Object();
+        Object o769 = new Object();
+        Object o770 = new Object();
+        Object o771 = new Object();
+        Object o772 = new Object();
+        Object o773 = new Object();
+        Object o774 = new Object();
+        Object o775 = new Object();
+        Object o776 = new Object();
+        Object o777 = new Object();
+        Object o778 = new Object();
+        Object o779 = new Object();
+        Object o780 = new Object();
+        Object o781 = new Object();
+        Object o782 = new Object();
+        Object o783 = new Object();
+        Object o784 = new Object();
+        Object o785 = new Object();
+        Object o786 = new Object();
+        Object o787 = new Object();
+        Object o788 = new Object();
+        Object o789 = new Object();
+        Object o790 = new Object();
+        Object o791 = new Object();
+        Object o792 = new Object();
+        Object o793 = new Object();
+        Object o794 = new Object();
+        Object o795 = new Object();
+        Object o796 = new Object();
+        Object o797 = new Object();
+        Object o798 = new Object();
+        Object o799 = new Object();
+        Object o800 = new Object();
+        Object o801 = new Object();
+        Object o802 = new Object();
+        Object o803 = new Object();
+        Object o804 = new Object();
+        Object o805 = new Object();
+        Object o806 = new Object();
+        Object o807 = new Object();
+        Object o808 = new Object();
+        Object o809 = new Object();
+        Object o810 = new Object();
+        Object o811 = new Object();
+        Object o812 = new Object();
+        Object o813 = new Object();
+        Object o848 = new Object();
+        Object o849 = new Object();
+        Object o850 = new Object();
+        Object o851 = new Object();
+        Object o852 = new Object();
+        Object o853 = new Object();
+        Object o854 = new Object();
+        Object o855 = new Object();
+        Object o856 = new Object();
+        Object o857 = new Object();
+        Object o858 = new Object();
+        Object o859 = new Object();
+        Object o860 = new Object();
+        Object o861 = new Object();
+        Object o862 = new Object();
+        Object o863 = new Object();
+        Object o864 = new Object();
+        Object o865 = new Object();
+        Object o866 = new Object();
+        Object o867 = new Object();
+        Object o868 = new Object();
+        Object o869 = new Object();
+        Object o870 = new Object();
+        Object o871 = new Object();
+        Object o872 = new Object();
+        Object o873 = new Object();
+        Object o874 = new Object();
+        Object o875 = new Object();
+        Object o876 = new Object();
+        Object o877 = new Object();
+        Object o878 = new Object();
+        Object o879 = new Object();
+        Object o880 = new Object();
+        Object o881 = new Object();
+        Object o882 = new Object();
+        Object o883 = new Object();
+        Object o884 = new Object();
+        Object o885 = new Object();
+        Object o886 = new Object();
+        Object o887 = new Object();
+        Object o888 = new Object();
+        Object o889 = new Object();
+        Object o890 = new Object();
+        Object o891 = new Object();
+        Object o892 = new Object();
+        Object o893 = new Object();
+        Object o894 = new Object();
+        Object o895 = new Object();
+        Object o896 = new Object();
+        Object o897 = new Object();
+        Object o898 = new Object();
+        Object o899 = new Object();
+        Object o900 = new Object();
+        Object o901 = new Object();
+        Object o902 = new Object();
+        Object o903 = new Object();
+        Object o904 = new Object();
+        Object o905 = new Object();
+        Object o906 = new Object();
+        Object o907 = new Object();
+        Object o908 = new Object();
+        Object o909 = new Object();
+        Object o910 = new Object();
+        Object o911 = new Object();
+        Object o912 = new Object();
+        Object o913 = new Object();
+        Object o914 = new Object();
+        Object o915 = new Object();
+        Object o916 = new Object();
+        Object o917 = new Object();
+        Object o918 = new Object();
+        Object o919 = new Object();
+        Object o920 = new Object();
+        Object o921 = new Object();
+        Object o922 = new Object();
+        Object o923 = new Object();
+        Object o924 = new Object();
+        Object o925 = new Object();
+        Object o926 = new Object();
+        Object o927 = new Object();
+        Object o928 = new Object();
+        Object o929 = new Object();
+        Object o930 = new Object();
+        Object o931 = new Object();
+        Object o932 = new Object();
+        Object o933 = new Object();
+        Object o934 = new Object();
+        Object o935 = new Object();
+        Object o936 = new Object();
+        Object o937 = new Object();
+        Object o938 = new Object();
+        Object o939 = new Object();
+        Object o940 = new Object();
+        Object o941 = new Object();
+        Object o942 = new Object();
+        Object o943 = new Object();
+        Object o944 = new Object();
+        Object o945 = new Object();
+        Object o946 = new Object();
+        Object o947 = new Object();
+        Object o948 = new Object();
+        Object o949 = new Object();
+        Object o950 = new Object();
+        Object o951 = new Object();
+        Object o952 = new Object();
+        Object o953 = new Object();
+        Object o954 = new Object();
+        Object o955 = new Object();
+        Object o956 = new Object();
+        Object o957 = new Object();
+        Object o958 = new Object();
+        Object o959 = new Object();
+        Object o960 = new Object();
+        Object o961 = new Object();
+        Object o962 = new Object();
+        Object o963 = new Object();
+        Object o964 = new Object();
+        Object o965 = new Object();
+        Object o966 = new Object();
+        Object o967 = new Object();
+        Object o968 = new Object();
+        Object o969 = new Object();
+        Object o970 = new Object();
+        Object o971 = new Object();
+        Object o972 = new Object();
+        Object o973 = new Object();
+        Object o974 = new Object();
+        Object o975 = new Object();
+        Object o976 = new Object();
+        Object o977 = new Object();
+        Object o978 = new Object();
+        Object o979 = new Object();
+        Object o980 = new Object();
+        Object o981 = new Object();
+        Object o982 = new Object();
+        Object o983 = new Object();
+        Object o984 = new Object();
+        Object o985 = new Object();
+        Object o986 = new Object();
+        Object o987 = new Object();
+        Object o988 = new Object();
+        Object o989 = new Object();
+        Object o990 = new Object();
+        Object o991 = new Object();
+        Object o992 = new Object();
+        Object o993 = new Object();
+        Object o994 = new Object();
+        Object o995 = new Object();
+        Object o996 = new Object();
+        Object o997 = new Object();
+        Object o998 = new Object();
+        Object o999 = new Object();
+    }
+
+    static class Deep0 {}
+    static class Deep1 extends Deep0 {}
+    static class Deep2 extends Deep1 {}
+    static class Deep3 extends Deep2 {}
+    static class Deep4 extends Deep3 {}
+    static class Deep5 extends Deep4 {}
+    static class Deep6 extends Deep5 {}
+    static class Deep7 extends Deep6 {}
+    static class Deep8 extends Deep7 {}
+    static class Deep9 extends Deep8 {}
+    static class Deep10 extends Deep9 {}
+    static class Deep11 extends Deep10 {}
+    static class Deep12 extends Deep11 {}
+    static class Deep13 extends Deep12 {}
+    static class Deep14 extends Deep13 {}
+    static class Deep15 extends Deep14 {}
+    static class Deep16 extends Deep15 {}
+    static class Deep17 extends Deep16 {}
+    static class Deep18 extends Deep17 {}
+    static class Deep19 extends Deep18 {}
+    static class Deep20 extends Deep19 {}
+    static class Deep21 extends Deep20 {}
+    static class Deep22 extends Deep21 {}
+    static class Deep23 extends Deep22 {}
+    static class Deep24 extends Deep23 {}
+    static class Deep25 extends Deep24 {}
+    static class Deep26 extends Deep25 {}
+    static class Deep27 extends Deep26 {}
+    static class Deep28 extends Deep27 {}
+    static class Deep29 extends Deep28 {}
+    static class Deep30 extends Deep29 {}
+    static class Deep31 extends Deep30 {}
+    static class Deep32 extends Deep31 {}
+    static class Deep33 extends Deep32 {}
+    static class Deep34 extends Deep33 {}
+    static class Deep35 extends Deep34 {}
+    static class Deep36 extends Deep35 {}
+    static class Deep37 extends Deep36 {}
+    static class Deep38 extends Deep37 {}
+    static class Deep39 extends Deep38 {}
+    static class Deep40 extends Deep39 {}
+    static class Deep41 extends Deep40 {}
+    static class Deep42 extends Deep41 {}
+    static class Deep43 extends Deep42 {}
+    static class Deep44 extends Deep43 {}
+    static class Deep45 extends Deep44 {}
+    static class Deep46 extends Deep45 {}
+    static class Deep47 extends Deep46 {}
+    static class Deep48 extends Deep47 {}
+    static class Deep49 extends Deep48 {}
+    static class Deep50 extends Deep49 {}
+    static class Deep51 extends Deep50 {}
+    static class Deep52 extends Deep51 {}
+    static class Deep53 extends Deep52 {}
+    static class Deep54 extends Deep53 {}
+    static class Deep55 extends Deep54 {}
+    static class Deep56 extends Deep55 {}
+    static class Deep57 extends Deep56 {}
+    static class Deep58 extends Deep57 {}
+    static class Deep59 extends Deep58 {}
+    static class Deep60 extends Deep59 {}
+    static class Deep61 extends Deep60 {}
+    static class Deep62 extends Deep61 {}
+    static class Deep63 extends Deep62 {}
+    static class Deep64 extends Deep63 {}
+    static class Deep65 extends Deep64 {}
+    static class Deep66 extends Deep65 {}
+    static class Deep67 extends Deep66 {}
+    static class Deep68 extends Deep67 {}
+    static class Deep69 extends Deep68 {}
+    static class Deep70 extends Deep69 {}
+    static class Deep71 extends Deep70 {}
+    static class Deep72 extends Deep71 {}
+    static class Deep73 extends Deep72 {}
+    static class Deep74 extends Deep73 {}
+    static class Deep75 extends Deep74 {}
+    static class Deep76 extends Deep75 {}
+    static class Deep77 extends Deep76 {}
+    static class Deep78 extends Deep77 {}
+    static class Deep79 extends Deep78 {}
+    static class Deep80 extends Deep79 {}
+    static class Deep81 extends Deep80 {}
+    static class Deep82 extends Deep81 {}
+    static class Deep83 extends Deep82 {}
+    static class Deep84 extends Deep83 {}
+    static class Deep85 extends Deep84 {}
+    static class Deep86 extends Deep85 {}
+    static class Deep87 extends Deep86 {}
+    static class Deep88 extends Deep87 {}
+    static class Deep89 extends Deep88 {}
+    static class Deep90 extends Deep89 {}
+    static class Deep91 extends Deep90 {}
+    static class Deep92 extends Deep91 {}
+    static class Deep93 extends Deep92 {}
+    static class Deep94 extends Deep93 {}
+    static class Deep95 extends Deep94 {}
+    static class Deep96 extends Deep95 {}
+    static class Deep97 extends Deep96 {}
+    static class Deep98 extends Deep97 {}
+    static class Deep99 extends Deep98 {}
+    static class Deep100 extends Deep99 {}
+
+    static class DeepCloneable extends Deep100 implements Cloneable {
+        public Object clone() throws CloneNotSupportedException {
+            return super.clone();
+        }
+    }
+
+    public void time_Object_clone(int reps) {
+        try {
+            CloneableObject o = new CloneableObject();
+            for (int rep = 0; rep < reps; ++rep) {
+                o.clone();
+            }
+        } catch (Exception e) {
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    public void time_Object_manyFieldClone(int reps) {
+        try {
+            CloneableManyFieldObject o = new CloneableManyFieldObject();
+            for (int rep = 0; rep < reps; ++rep) {
+                o.clone();
+            }
+        } catch (Exception e) {
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    public void time_Object_deepClone(int reps) {
+        try {
+            DeepCloneable o = new DeepCloneable();
+            for (int rep = 0; rep < reps; ++rep) {
+                o.clone();
+            }
+        } catch (Exception e) {
+            throw new AssertionError(e.getMessage());
+        }
+    }
+
+    public void time_Array_clone(int reps) {
+        int[] o = new int[32];
+        for (int rep = 0; rep < reps; ++rep) {
+            o.clone();
+        }
+    }
+
+    public void time_ObjectArray_smallClone(int reps) {
+        Object[] o = new Object[32];
+        for (int i = 0; i < o.length / 2; ++i) {
+            o[i] = new Object();
+        }
+        for (int rep = 0; rep < reps; ++rep) {
+            o.clone();
+        }
+    }
+
+    public void time_ObjectArray_largeClone(int reps) {
+        Object[] o = new Object[2048];
+        for (int i = 0; i < o.length / 2; ++i) {
+            o[i] = new Object();
+        }
+        for (int rep = 0; rep < reps; ++rep) {
+            o.clone();
+        }
+    }
+}
diff --git a/benchmarks/src/benchmarks/regression/DateFormatBenchmark.java b/benchmarks/src/benchmarks/regression/DateFormatBenchmark.java
new file mode 100644
index 0000000..bd5bf1a
--- /dev/null
+++ b/benchmarks/src/benchmarks/regression/DateFormatBenchmark.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package benchmarks.regression;
+
+import com.google.caliper.BeforeExperiment;
+
+import java.text.DateFormat;
+import java.util.Locale;
+
+public final class DateFormatBenchmark {
+
+    private Locale locale1;
+    private Locale locale2;
+    private Locale locale3;
+    private Locale locale4;
+
+    @BeforeExperiment
+    protected void setUp() throws Exception {
+        locale1 = Locale.TAIWAN;
+        locale2 = Locale.GERMANY;
+        locale3 = Locale.FRANCE;
+        locale4 = Locale.ITALY;
+    }
+
+    public void timeGetDateTimeInstance(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            DateFormat.getDateTimeInstance();
+        }
+    }
+
+    public void timeGetDateTimeInstance_multiple(int reps) throws Exception {
+        for (int i = 0; i < reps; ++i) {
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale1);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale2);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale3);
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale4);
+        }
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/system/CloseGuard.java b/dalvik/src/main/java/dalvik/system/CloseGuard.java
index a45ffa1..e718ee7 100644
--- a/dalvik/src/main/java/dalvik/system/CloseGuard.java
+++ b/dalvik/src/main/java/dalvik/system/CloseGuard.java
@@ -118,6 +118,16 @@
     private static volatile Reporter REPORTER = new DefaultReporter();
 
     /**
+     * The default {@link Tracker}.
+     */
+    private static final DefaultTracker DEFAULT_TRACKER = new DefaultTracker();
+
+    /**
+     * Hook for customizing how CloseGuard issues are tracked.
+     */
+    private static volatile Tracker currentTracker = DEFAULT_TRACKER;
+
+    /**
      * Returns a CloseGuard instance. If CloseGuard is enabled, {@code
      * #open(String)} can be used to set up the instance to warn on
      * failure to close. If CloseGuard is disabled, a non-null no-op
@@ -139,6 +149,13 @@
     }
 
     /**
+     * True if CloseGuard mechanism is enabled.
+     */
+    public static boolean isEnabled() {
+        return ENABLED;
+    }
+
+    /**
      * Used to replace default Reporter used to warn of CloseGuard
      * violations. Must be non-null.
      */
@@ -156,6 +173,32 @@
         return REPORTER;
     }
 
+    /**
+     * Sets the {@link Tracker} that is notified when resources are allocated and released.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     *
+     * @throws NullPointerException if tracker is null
+     */
+    public static void setTracker(Tracker tracker) {
+        if (tracker == null) {
+            throw new NullPointerException("tracker == null");
+        }
+        currentTracker = tracker;
+    }
+
+    /**
+     * Returns {@link #setTracker(Tracker) last Tracker that was set}, or otherwise a default
+     * Tracker that does nothing.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public static Tracker getTracker() {
+        return currentTracker;
+    }
+
     private CloseGuard() {}
 
     /**
@@ -178,6 +221,7 @@
         }
         String message = "Explicit termination method '" + closer + "' not called";
         allocationSite = new Throwable(message);
+        currentTracker.open(allocationSite);
     }
 
     private Throwable allocationSite;
@@ -187,6 +231,7 @@
      * finalization.
      */
     public void close() {
+        currentTracker.close(allocationSite);
         allocationSite = null;
     }
 
@@ -209,10 +254,35 @@
     }
 
     /**
+     * Interface to allow customization of tracking behaviour.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public interface Tracker {
+        void open(Throwable allocationSite);
+        void close(Throwable allocationSite);
+    }
+
+    /**
+     * Default tracker which does nothing special and simply leaves it up to the GC to detect a
+     * leak.
+     */
+    private static final class DefaultTracker implements Tracker {
+        @Override
+        public void open(Throwable allocationSite) {
+        }
+
+        @Override
+        public void close(Throwable allocationSite) {
+        }
+    }
+
+    /**
      * Interface to allow customization of reporting behavior.
      */
-    public static interface Reporter {
-        public void report (String message, Throwable allocationSite);
+    public interface Reporter {
+        void report (String message, Throwable allocationSite);
     }
 
     /**
diff --git a/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java b/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java
deleted file mode 100644
index b5bf380..0000000
--- a/dalvik/src/test/java/dalvik/system/CloseGuardMonitor.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package dalvik.system;
-
-import dalvik.system.CloseGuard.Reporter;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Provides support for detecting issues found by {@link CloseGuard} from within tests.
- *
- * <p>This is a best effort as it relies on both {@link CloseGuard} being enabled and being able to
- * force a GC and finalization, none of which are directly controllable by this.
- *
- * <p>This is loaded using reflection by the AbstractResourceLeakageDetectorTestCase class as that
- * class needs to run on the reference implementation which does not have this class. It implements
- * {@link Runnable} because that is simpler than trying to manage a specialized interface.
- *
- * @hide
- */
-public class CloseGuardMonitor implements Runnable {
-  /**
-   * The {@link Reporter} instance used to receive warnings from {@link CloseGuard}.
-   */
-  private final Reporter closeGuardReporter;
-
-  /**
-   * The list of allocation sites that {@link CloseGuard} has reported as not being released.
-   *
-   * <p>Is thread safe as this will be called during finalization and so there are no guarantees
-   * as to whether it will be called concurrently or not.
-   */
-  private final List<Throwable> closeGuardAllocationSites = new CopyOnWriteArrayList<>();
-
-  /**
-   * Default constructor required for reflection.
-   */
-  public CloseGuardMonitor() {
-    System.logI("Creating CloseGuard monitor");
-
-    // Save current reporter.
-    closeGuardReporter = CloseGuard.getReporter();
-
-    // Override the reporter with our own which collates the allocation sites.
-    CloseGuard.setReporter(new Reporter() {
-      @Override
-      public void report(String message, Throwable allocationSite) {
-        // Ignore message as it's always the same.
-        closeGuardAllocationSites.add(allocationSite);
-      }
-    });
-  }
-
-  /**
-   * Check to see whether any resources monitored by {@link CloseGuard} were not released before
-   * they were garbage collected.
-   */
-  @Override
-  public void run() {
-    // Create a weak reference to an object so that we can detect when it is garbage collected.
-    WeakReference<Object> reference = new WeakReference<>(new Object());
-
-    try {
-      // 'Force' a GC and finalize to cause CloseGuards to report warnings. Doesn't loop
-      // forever as there are no guarantees that the following code does anything at all so
-      // don't want a potential infinite loop.
-      Runtime runtime = Runtime.getRuntime();
-      for (int i = 0; i < 20; ++i) {
-        runtime.gc();
-        System.runFinalization();
-        try {
-          Thread.sleep(1);
-        } catch (InterruptedException e) {
-          throw new AssertionError(e);
-        }
-
-        // Check to see if the weak reference has been garbage collected.
-        if (reference.get() == null) {
-          System.logI("Sentry object has been freed so assuming CloseGuards have reported"
-              + " any resource leakages");
-          break;
-        }
-      }
-    } finally {
-      // Restore the reporter.
-      CloseGuard.setReporter(closeGuardReporter);
-    }
-
-    if (!closeGuardAllocationSites.isEmpty()) {
-      StringWriter writer = new StringWriter();
-      PrintWriter printWriter = new PrintWriter(writer);
-      int i = 0;
-      for (Throwable allocationSite : closeGuardAllocationSites) {
-        printWriter.print(++i);
-        printWriter.print(") ");
-        allocationSite.printStackTrace(printWriter);
-        printWriter.println("    --------------------------------");
-      }
-      throw new AssertionError("Potential resource leakage detected:\n" + writer);
-    }
-  }
-}
diff --git a/dalvik/src/test/java/dalvik/system/CloseGuardTest.java b/dalvik/src/test/java/dalvik/system/CloseGuardTest.java
new file mode 100644
index 0000000..a1d1f42
--- /dev/null
+++ b/dalvik/src/test/java/dalvik/system/CloseGuardTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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 dalvik.system;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Tests {@link CloseGuard}.
+ */
+public class CloseGuardTest {
+
+    /**
+     * Resets the {@link CloseGuard#ENABLED} state back to the value it had when the test started.
+     */
+    @Rule
+    public TestRule rule = this::preserveEnabledState;
+
+    private Statement preserveEnabledState(final Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                boolean oldEnabledState = CloseGuard.isEnabled();
+                try {
+                    base.evaluate();
+                } finally {
+                    CloseGuard.setEnabled(oldEnabledState);
+                }
+            }
+        };
+    }
+
+    @Test
+    public void testEnabled_NotOpen() throws Throwable {
+        CloseGuard.setEnabled(true);
+        ResourceOwner owner = new ResourceOwner();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testEnabled_OpenNotClosed() throws Throwable {
+        CloseGuard.setEnabled(true);
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        assertUnreleasedResources(owner, 1);
+    }
+
+    @Test
+    public void testEnabled_OpenThenClosed() throws Throwable {
+        CloseGuard.setEnabled(true);
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        owner.close();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testEnabledWhenCreated_DisabledWhenOpen() throws Throwable {
+        CloseGuard.setEnabled(true);
+        ResourceOwner owner = new ResourceOwner();
+        CloseGuard.setEnabled(false);
+        owner.open();
+
+        // Although the resource was not released it should not report it because CloseGuard was
+        // not enabled when the CloseGuard was opened.
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testEnabledWhenOpened_DisabledWhenFinalized() throws Throwable {
+        CloseGuard.setEnabled(true);
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        CloseGuard.setEnabled(false);
+
+        // Although the resource was not released it should not report it because CloseGuard was
+        // not enabled when the CloseGuard was finalized.
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testDisabled_NotOpen() throws Throwable {
+        CloseGuard.setEnabled(false);
+        ResourceOwner owner = new ResourceOwner();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testDisabled_OpenNotClosed() throws Throwable {
+        CloseGuard.setEnabled(false);
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testDisabled_OpenThenClosed() throws Throwable {
+        CloseGuard.setEnabled(false);
+        ResourceOwner owner = new ResourceOwner();
+        owner.open();
+        owner.close();
+        assertUnreleasedResources(owner, 0);
+    }
+
+    @Test
+    public void testDisabledWhenCreated_EnabledWhenOpen() throws Throwable {
+        CloseGuard.setEnabled(false);
+        ResourceOwner owner = new ResourceOwner();
+        CloseGuard.setEnabled(true);
+        owner.open();
+
+        // Although the resource was not released it should not report it because CloseGuard was
+        // not enabled when the CloseGuard was created.
+        assertUnreleasedResources(owner, 0);
+    }
+
+    private void assertUnreleasedResources(ResourceOwner owner, int expectedCount)
+            throws Throwable {
+        try {
+            CloseGuardSupport.getFinalizerChecker().accept(owner, expectedCount);
+        } finally {
+            // Close the resource so that CloseGuard does not generate a warning for real when it
+            // is actually finalized.
+            owner.close();
+        }
+    }
+
+    /**
+     * A test user of {@link CloseGuard}.
+     */
+    private static class ResourceOwner {
+
+        private final CloseGuard closeGuard;
+
+        ResourceOwner() {
+            closeGuard = CloseGuard.get();
+        }
+
+        public void open() {
+            closeGuard.open("close");
+        }
+
+        public void close() {
+            closeGuard.close();
+        }
+
+        /**
+         * Make finalize public so that it can be tested directly without relying on garbage
+         * collection to trigger it.
+         */
+        @Override
+        public void finalize() throws Throwable {
+            closeGuard.warnIfOpen();
+            super.finalize();
+        }
+    }
+}
diff --git a/dalvik/test-rules/src/main/java/dalvik/system/CloseGuardSupport.java b/dalvik/test-rules/src/main/java/dalvik/system/CloseGuardSupport.java
new file mode 100644
index 0000000..7871795
--- /dev/null
+++ b/dalvik/test-rules/src/main/java/dalvik/system/CloseGuardSupport.java
@@ -0,0 +1,286 @@
+/*
+ * 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 dalvik.system;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.BiConsumer;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Provides support for testing classes that use {@link CloseGuard} in order to detect resource
+ * leakages.
+ *
+ * <p>This class should not be used directly by tests as that will prevent them from being
+ * compilable and testable on OpenJDK platform. Instead they should use
+ * {@code libcore.junit.util.ResourceLeakageDetector} which accesses the capabilities of this using
+ * reflection and if it cannot find it (because it is running on OpenJDK) then it will just skip
+ * leakage detection.
+ *
+ * <p>This provides two entry points that are accessed reflectively:
+ * <ul>
+ * <li>
+ * <p>The {@link #getRule()} method. This returns a {@link TestRule} that will fail a test if it
+ * detects any resources that were allocated during the test but were not released.
+ *
+ * <p>This only tracks resources that were allocated on the test thread, although it does not care
+ * what thread they were released on. This avoids flaky false positives where a background thread
+ * allocates a resource during a test but releases it after the test.
+ *
+ * <p>It is still possible to have a false positive in the case where the test causes a caching
+ * mechanism to open a resource and hold it open past the end of the test. In that case if there is
+ * no way to clear the cached data then it should be relatively simple to move the code that invokes
+ * the caching mechanism to outside the scope of this rule. i.e.
+ *
+ * <pre>{@code
+ *     @Rule
+ *     public final TestRule ruleChain = org.junit.rules.RuleChain
+ *         .outerRule(new ...invoke caching mechanism...)
+ *         .around(CloseGuardSupport.getRule());
+ * }</pre>
+ * </li>
+ * <li>
+ * <p>The {@link #getFinalizerChecker()} method. This returns a {@link BiConsumer} that takes an
+ * object that owns resources and an expected number of unreleased resources. It will call the
+ * {@link Object#finalize()} method on the object using reflection and throw an
+ * {@link AssertionError} if the number of reported unreleased resources does not match the
+ * expected number.
+ * </li>
+ * </ul>
+ */
+public class CloseGuardSupport {
+
+    private static final TestRule CLOSE_GUARD_RULE = new FailTestWhenResourcesNotClosedRule();
+
+    /**
+     * Get a {@link TestRule} that will detect when resources that use the {@link CloseGuard}
+     * mechanism are not cleaned up properly by a test.
+     *
+     * <p>If the {@link CloseGuard} mechanism is not supported, e.g. on OpenJDK, then the returned
+     * rule does nothing.
+     */
+    public static TestRule getRule() {
+        return CLOSE_GUARD_RULE;
+    }
+
+    private CloseGuardSupport() {
+    }
+
+    /**
+     * Fails a test when resources are not cleaned up properly.
+     */
+    private static class FailTestWhenResourcesNotClosedRule implements TestRule {
+        /**
+         * Returns a {@link Statement} that will fail the test if it ends with unreleased resources.
+         * @param base the test to be run.
+         */
+        public Statement apply(Statement base, Description description) {
+            return new Statement() {
+                @Override
+                public void evaluate() throws Throwable {
+                    // Get the previous tracker so that it can be restored afterwards.
+                    CloseGuard.Tracker previousTracker = CloseGuard.getTracker();
+                    // Get the previous enabled state so that it can be restored afterwards.
+                    boolean previousEnabled = CloseGuard.isEnabled();
+                    TestCloseGuardTracker tracker = new TestCloseGuardTracker();
+                    Throwable thrown = null;
+                    try {
+                        // Set the test tracker and enable close guard detection.
+                        CloseGuard.setTracker(tracker);
+                        CloseGuard.setEnabled(true);
+                        base.evaluate();
+                    } catch (Throwable throwable) {
+                        // Catch and remember the throwable so that it can be rethrown in the
+                        // finally block.
+                        thrown = throwable;
+                    } finally {
+                        // Restore the previous tracker and enabled state.
+                        CloseGuard.setEnabled(previousEnabled);
+                        CloseGuard.setTracker(previousTracker);
+
+                        Collection<Throwable> allocationSites =
+                                tracker.getAllocationSitesForUnreleasedResources();
+                        if (!allocationSites.isEmpty()) {
+                            if (thrown == null) {
+                                thrown = new IllegalStateException(
+                                        "Unreleased resources found in test");
+                            }
+                            for (Throwable allocationSite : allocationSites) {
+                                thrown.addSuppressed(allocationSite);
+                            }
+                        }
+                        if (thrown != null) {
+                            throw thrown;
+                        }
+                    }
+                }
+            };
+        }
+    }
+
+    /**
+     * A tracker that keeps a record of the allocation sites for all resources allocated but not
+     * yet released.
+     *
+     * <p>It only tracks resources allocated for the test thread.
+     */
+    private static class TestCloseGuardTracker implements CloseGuard.Tracker {
+
+        /**
+         * A set would be preferable but this is the closest that matches the concurrency
+         * requirements for the use case which prioritise speed of addition and removal over
+         * iteration and access.
+         */
+        private final Set<Throwable> allocationSites =
+                Collections.newSetFromMap(new ConcurrentHashMap<>());
+
+        private final Thread testThread = Thread.currentThread();
+
+        @Override
+        public void open(Throwable allocationSite) {
+            if (Thread.currentThread() == testThread) {
+                allocationSites.add(allocationSite);
+            }
+        }
+
+        @Override
+        public void close(Throwable allocationSite) {
+            // Closing the resource twice could pass null into here.
+            if (allocationSite != null) {
+                allocationSites.remove(allocationSite);
+            }
+        }
+
+        /**
+         * Get the collection of allocation sites for any unreleased resources.
+         */
+        Collection<Throwable> getAllocationSitesForUnreleasedResources() {
+            return new ArrayList<>(allocationSites);
+        }
+    }
+
+    private static final BiConsumer<Object, Integer> FINALIZER_CHECKER
+            = new BiConsumer<Object, Integer>() {
+        @Override
+        public void accept(Object resourceOwner, Integer expectedCount) {
+            finalizerChecker(resourceOwner, expectedCount);
+        }
+    };
+
+    /**
+     * Get access to a {@link BiConsumer} that will determine how many unreleased resources the
+     * first parameter owns and throw a {@link AssertionError} if that does not match the
+     * expected number of resources specified by the second parameter.
+     *
+     * <p>This uses a {@link BiConsumer} as it is a standard interface that is available in all
+     * environments. That helps avoid the caller from having compile time dependencies on this
+     * class which will not be available on OpenJDK.
+     */
+    public static BiConsumer<Object, Integer> getFinalizerChecker() {
+        return FINALIZER_CHECKER;
+    }
+
+    /**
+     * Checks that the supplied {@code resourceOwner} has overridden the {@link Object#finalize()}
+     * method and uses {@link CloseGuard#warnIfOpen()} correctly to detect when the resource is
+     * not released.
+     *
+     * @param resourceOwner the owner of the resource protected by {@link CloseGuard}.
+     * @param expectedCount the expected number of unreleased resources to be held by the owner.
+     *
+     */
+    private static void finalizerChecker(Object resourceOwner, int expectedCount) {
+        Class<?> clazz = resourceOwner.getClass();
+        Method finalizer = null;
+        while (clazz != null && clazz != Object.class) {
+            try {
+                finalizer = clazz.getDeclaredMethod("finalize");
+                break;
+            } catch (NoSuchMethodException e) {
+                // Carry on up the class hierarchy.
+                clazz = clazz.getSuperclass();
+            }
+        }
+
+        if (finalizer == null) {
+            // No finalizer method could be found.
+            throw new AssertionError("Class " + resourceOwner.getClass().getName()
+                    + " does not have a finalize() method");
+        }
+
+        // Make the method accessible.
+        finalizer.setAccessible(true);
+
+        CloseGuard.Reporter oldReporter = CloseGuard.getReporter();
+        try {
+            CollectingReporter reporter = new CollectingReporter();
+            CloseGuard.setReporter(reporter);
+
+            // Invoke the finalizer to cause it to get CloseGuard to report a problem if it has
+            // not yet been closed.
+            try {
+                finalizer.invoke(resourceOwner);
+            } catch (ReflectiveOperationException e) {
+                throw new AssertionError(
+                        "Could not invoke the finalizer() method on " + resourceOwner, e);
+            }
+
+            reporter.assertUnreleasedResources(expectedCount);
+        } finally {
+            CloseGuard.setReporter(oldReporter);
+        }
+    }
+
+    /**
+     * A {@link CloseGuard.Reporter} that collects any reports about unreleased resources.
+     */
+    private static class CollectingReporter implements CloseGuard.Reporter {
+
+        private final Thread callingThread = Thread.currentThread();
+
+        private final List<Throwable> unreleasedResourceAllocationSites = new ArrayList<>();
+
+        @Override
+        public void report(String message, Throwable allocationSite) {
+            // Only care about resources that are not reported on this thread.
+            if (callingThread == Thread.currentThread()) {
+                unreleasedResourceAllocationSites.add(allocationSite);
+            }
+        }
+
+        void assertUnreleasedResources(int expectedCount) {
+            int unreleasedResourceCount = unreleasedResourceAllocationSites.size();
+            if (unreleasedResourceCount == expectedCount) {
+                return;
+            }
+
+            AssertionError error = new AssertionError(
+                    "Expected " + expectedCount + " unreleased resources, found "
+                            + unreleasedResourceCount + "; see suppressed exceptions for details");
+            for (Throwable unreleasedResourceAllocationSite : unreleasedResourceAllocationSites) {
+                error.addSuppressed(unreleasedResourceAllocationSite);
+            }
+            throw error;
+        }
+    }
+}
diff --git a/dalvik/test-rules/src/test/java/dalvik/system/CloseGuardSupportTest.java b/dalvik/test-rules/src/test/java/dalvik/system/CloseGuardSupportTest.java
new file mode 100644
index 0000000..fe05710
--- /dev/null
+++ b/dalvik/test-rules/src/test/java/dalvik/system/CloseGuardSupportTest.java
@@ -0,0 +1,182 @@
+/*
+ * 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 dalvik.system;
+
+import java.util.Collections;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.JUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@RunWith(JUnit4.class)
+public class CloseGuardSupportTest {
+
+    @Test
+    public void testDoesReleaseResource() {
+        List<Failure> failures = JUnitCore.runClasses(DoesReleaseResource.class).getFailures();
+        assertEquals(Collections.emptyList(), failures);
+    }
+
+    public static class DoesReleaseResource {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test public void test() {
+            CloseGuard closeGuard = CloseGuard.get();
+            closeGuard.open("test resource");
+            closeGuard.close();
+        }
+    }
+
+    @Test
+    public void testDoesReleaseResourceTwice() {
+        List<Failure> failures = JUnitCore.runClasses(DoesReleaseResourceTwice.class).getFailures();
+        assertEquals(Collections.emptyList(), failures);
+    }
+
+    public static class DoesReleaseResourceTwice {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test public void test() {
+            CloseGuard closeGuard = CloseGuard.get();
+            closeGuard.open("test resource");
+            closeGuard.close();
+            closeGuard.close();
+        }
+    }
+
+    @Test
+    public void testDoesNotReleaseResource() {
+        List<Failure> failures = JUnitCore.runClasses(DoesNotReleaseResource.class).getFailures();
+        assertEquals("Failure count", 1, failures.size());
+        Failure failure = failures.get(0);
+        checkResourceNotReleased(failure, "Unreleased resources found in test");
+    }
+
+    public static class DoesNotReleaseResource {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test public void test() {
+            CloseGuard closeGuard = CloseGuard.get();
+            closeGuard.open("test resource");
+        }
+    }
+
+    @Test
+    public void testDoesNotReleaseResourceDueToFailure() {
+        List<Failure> failures = JUnitCore
+                .runClasses(DoesNotReleaseResourceDueToFailure.class)
+                .getFailures();
+        assertEquals("Failure count", 1, failures.size());
+        Failure failure = failures.get(0);
+        checkResourceNotReleased(failure, "failure");
+    }
+
+    public static class DoesNotReleaseResourceDueToFailure {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test public void test() {
+            CloseGuard closeGuard = CloseGuard.get();
+            closeGuard.open("test resource");
+            fail("failure");
+        }
+    }
+
+    @Test
+    public void testResourceOwnerDoesNotOverrideFinalize() {
+        List<Failure> failures = JUnitCore
+                .runClasses(ResourceOwnerDoesNotOverrideFinalize.class)
+                .getFailures();
+        assertEquals("Failure count", 1, failures.size());
+        Failure failure = failures.get(0);
+        assertEquals("Class java.lang.String does not have a finalize() method",
+                failure.getMessage());
+    }
+
+    public static class ResourceOwnerDoesNotOverrideFinalize {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test
+        public void test() {
+            CloseGuardSupport.getFinalizerChecker().accept("not resource owner", 0);
+        }
+    }
+
+    @Test
+    public void testResourceOwnerOverridesFinalizeButDoesNotReportLeak() {
+        List<Failure> failures = JUnitCore
+                .runClasses(ResourceOwnerOverridesFinalizeButDoesNotReportLeak.class)
+                .getFailures();
+        assertEquals("Failure count", 1, failures.size());
+        Failure failure = failures.get(0);
+        assertEquals("Expected 1 unreleased resources, found 0;"
+                        + " see suppressed exceptions for details",
+                failure.getMessage());
+    }
+
+    public static class ResourceOwnerOverridesFinalizeButDoesNotReportLeak {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test
+        public void test() {
+            CloseGuardSupport.getFinalizerChecker().accept(new Object() {
+                @Override
+                protected void finalize() throws Throwable {
+                    super.finalize();
+                }
+            }, 1);
+        }
+    }
+
+    @Test
+    public void testResourceOwnerOverridesFinalizeAndReportsLeak() {
+        List<Failure> failures = JUnitCore
+                .runClasses(ResourceOwnerOverridesFinalizeAndReportsLeak.class)
+                .getFailures();
+        assertEquals("Failure count", 1, failures.size());
+        Failure failure = failures.get(0);
+        checkResourceNotReleased(failure, "Unreleased resources found in test");
+    }
+
+    public static class ResourceOwnerOverridesFinalizeAndReportsLeak {
+        @Rule public TestRule rule = CloseGuardSupport.getRule();
+        @Test
+        public void test() {
+            CloseGuardSupport.getFinalizerChecker().accept(new Object() {
+                private CloseGuard guard = CloseGuard.get();
+                {
+                    guard.open("test resource");
+                }
+                @Override
+                protected void finalize() throws Throwable {
+                    guard.warnIfOpen();
+                    super.finalize();
+                }
+            }, 1);
+        }
+    }
+
+    private void checkResourceNotReleased(Failure failure, String expectedMessage) {
+        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+        Throwable exception = failure.getException();
+        assertEquals(expectedMessage, exception.getMessage());
+        Throwable[] suppressed = exception.getSuppressed();
+        assertEquals("Suppressed count", 1, suppressed.length);
+        exception = suppressed[0];
+        assertEquals("Explicit termination method 'test resource' not called",
+                exception.getMessage());
+    }
+}
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index 37c1a1d..8465a24 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -72,6 +72,12 @@
     private long strings;
 
     /**
+     * References to MethodType (C array pointer) as they become resolved following
+     * interpreter semantics.
+     */
+    private long resolvedMethodTypes;
+
+    /**
      * The number of elements in the native resolvedFields array.
      */
     private int numResolvedFields;
@@ -91,6 +97,11 @@
      */
     private int numStrings;
 
+    /**
+     * The number of elements in the native method types array.
+     */
+    private int numResolvedMethodTypes;
+
     // Only created by the VM.
     private DexCache() {}
 
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index acf9b39..dee5129 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -245,6 +245,7 @@
     public static final int JAVA_MCAST_BLOCK_SOURCE = 23;
     public static final int JAVA_MCAST_UNBLOCK_SOURCE = 24;
     public static final int JAVA_IP_MULTICAST_TTL = 17;
+    public static final int JAVA_IP_TTL = 25;
 
     /**
      * java.net has its own socket options similar to the underlying Unix ones. We paper over the
@@ -274,6 +275,10 @@
             // Since setting this from java.net always sets IPv4 and IPv6 to the same value,
             // it doesn't matter which we return.
             return Libcore.os.getsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
+        case IoBridge.JAVA_IP_TTL:
+            // Since setting this from java.net always sets IPv4 and IPv6 to the same value,
+            // it doesn't matter which we return.
+            return Libcore.os.getsockoptInt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS);
         case SocketOptions.IP_TOS:
             // Since setting this from java.net always sets IPv4 and IPv6 to the same value,
             // it doesn't matter which we return.
@@ -345,6 +350,10 @@
             Libcore.os.setsockoptByte(fd, IPPROTO_IP, IP_MULTICAST_TTL, (Integer) value);
             Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (Integer) value);
             return;
+        case IoBridge.JAVA_IP_TTL:
+            Libcore.os.setsockoptInt(fd, IPPROTO_IP, IP_TTL, (Integer) value);
+            Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (Integer) value);
+            return;
         case SocketOptions.IP_TOS:
             Libcore.os.setsockoptInt(fd, IPPROTO_IP, IP_TOS, (Integer) value);
             Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_TCLASS, (Integer) value);
@@ -606,17 +615,6 @@
         try {
             fd = Libcore.os.socket(AF_INET6, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
 
-            // The RFC (http://www.ietf.org/rfc/rfc3493.txt) says that IPV6_MULTICAST_HOPS defaults
-            // to 1. The Linux kernel (at least up to 2.6.38) accidentally defaults to 64 (which
-            // would be correct for the *unicast* hop limit).
-            // See http://www.spinics.net/lists/netdev/msg129022.html, though no patch appears to
-            // have been applied as a result of that discussion. If that bug is ever fixed, we can
-            // remove this code. Until then, we manually set the hop limit on IPv6 datagram sockets.
-            // (IPv4 is already correct.)
-            if (!stream) {
-                Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 1);
-            }
-
             return fd;
         } catch (ErrnoException errnoException) {
             throw errnoException.rethrowAsSocketException();
diff --git a/luni/src/main/native/ExecStrings.cpp b/luni/src/main/native/ExecStrings.cpp
index a6a62e2..4f90431 100644
--- a/luni/src/main/native/ExecStrings.cpp
+++ b/luni/src/main/native/ExecStrings.cpp
@@ -20,7 +20,8 @@
 
 #include <stdlib.h>
 
-#include "cutils/log.h"
+#include <android/log.h>
+
 #include "ScopedLocalRef.h"
 
 ExecStrings::ExecStrings(JNIEnv* env, jobjectArray java_string_array)
diff --git a/luni/src/main/native/IcuUtilities.cpp b/luni/src/main/native/IcuUtilities.cpp
index 98648a5..6b29e67 100644
--- a/luni/src/main/native/IcuUtilities.cpp
+++ b/luni/src/main/native/IcuUtilities.cpp
@@ -16,16 +16,17 @@
 
 #define LOG_TAG "IcuUtilities"
 
+#include <android/log.h>
+
 #include "IcuUtilities.h"
 
 #include "JniConstants.h"
 #include "JniException.h"
 #include "ScopedLocalRef.h"
 #include "ScopedUtfChars.h"
-#include "cutils/log.h"
 #include "unicode/strenum.h"
-#include "unicode/uloc.h"
 #include "unicode/ustring.h"
+#include "unicode/uloc.h"
 
 jobjectArray fromStringEnumeration(JNIEnv* env, UErrorCode& status, const char* provider, icu::StringEnumeration* se) {
   if (maybeThrowIcuException(env, provider, status)) {
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 52df40e..ec9d878 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -16,12 +16,13 @@
 
 #define LOG_TAG "libcore" // We'll be next to "dalvikvm" in the log; make the distinction clear.
 
-#include "cutils/log.h"
+#include <stdlib.h>
+
+#include "android/log.h"
+
 #include "JniConstants.h"
 #include "ScopedLocalFrame.h"
 
-#include <stdlib.h>
-
 // DalvikVM calls this on startup, so we can statically register all our native methods.
 jint JNI_OnLoad(JavaVM* vm, void*) {
     JNIEnv* env;
diff --git a/luni/src/main/native/java_math_NativeBN.cpp b/luni/src/main/native/java_math_NativeBN.cpp
index 45df4c5..559a702 100644
--- a/luni/src/main/native/java_math_NativeBN.cpp
+++ b/luni/src/main/native/java_math_NativeBN.cpp
@@ -139,23 +139,9 @@
   uint64_t dw = java_dw;
   BIGNUM* a = toBigNum(a0);
 
-  static_assert(sizeof(dw) == sizeof(BN_ULONG) ||
-                sizeof(dw) == 2*sizeof(BN_ULONG), "Unknown BN configuration");
-
-  if (sizeof(dw) == sizeof(BN_ULONG)) {
-    if (!BN_set_word(a, dw)) {
-      throwException(env);
-      return;
-    }
-  } else if (sizeof(dw) == 2 * sizeof(BN_ULONG)) {
-    if (!bn_wexpand(a, 2)) {
-      throwException(env);
-      return;
-    }
-    a->d[0] = dw;
-    a->d[1] = dw >> 32;
-    a->top = 2;
-    bn_correct_top(a);
+  if (!BN_set_u64(a, dw)) {
+    throwException(env);
+    return;
   }
 
   BN_set_negative(a, neg);
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index e6f378e..7456028 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -16,6 +16,24 @@
 
 #define LOG_TAG "ICU"
 
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <memory>
+#include <vector>
+
+#include <android/log.h>
+#include <android-base/unique_fd.h>
+
 #include "IcuUtilities.h"
 #include "JNIHelp.h"
 #include "JniConstants.h"
@@ -24,7 +42,6 @@
 #include "ScopedJavaUnicodeString.h"
 #include "ScopedLocalRef.h"
 #include "ScopedUtfChars.h"
-#include "cutils/log.h"
 #include "toStringArray.h"
 #include "unicode/brkiter.h"
 #include "unicode/calendar.h"
@@ -51,22 +68,6 @@
 #include "ureslocs.h"
 #include "valueOf.h"
 
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <string>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <memory>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-
 class ScopedResourceBundle {
  public:
   explicit ScopedResourceBundle(UResourceBundle* bundle) : bundle_(bundle) {
diff --git a/luni/src/main/native/libcore_icu_NativeConverter.cpp b/luni/src/main/native/libcore_icu_NativeConverter.cpp
index bf938d1..f78ca19 100644
--- a/luni/src/main/native/libcore_icu_NativeConverter.cpp
+++ b/luni/src/main/native/libcore_icu_NativeConverter.cpp
@@ -15,6 +15,14 @@
 
 #define LOG_TAG "NativeConverter"
 
+#include <stdlib.h>
+#include <string.h>
+
+#include <memory>
+#include <vector>
+
+#include <android/log.h>
+
 #include "IcuUtilities.h"
 #include "JNIHelp.h"
 #include "JniConstants.h"
@@ -23,7 +31,6 @@
 #include "ScopedPrimitiveArray.h"
 #include "ScopedStringChars.h"
 #include "ScopedUtfChars.h"
-#include "cutils/log.h"
 #include "toStringArray.h"
 #include "unicode/ucnv.h"
 #include "unicode/ucnv_cb.h"
@@ -31,12 +38,6 @@
 #include "unicode/ustring.h"
 #include "unicode/utypes.h"
 
-#include <memory>
-#include <vector>
-
-#include <stdlib.h>
-#include <string.h>
-
 #define NativeConverter_REPORT 0
 #define NativeConverter_IGNORE 1
 #define NativeConverter_REPLACE 2
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index d0b3924..f8fd199 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -16,20 +16,6 @@
 
 #define LOG_TAG "Posix"
 
-#include "AsynchronousCloseMonitor.h"
-#include "cutils/log.h"
-#include "ExecStrings.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "NetworkUtilities.h"
-#include "Portability.h"
-#include "ScopedBytes.h"
-#include "ScopedLocalRef.h"
-#include "ScopedPrimitiveArray.h"
-#include "ScopedUtfChars.h"
-#include "toStringArray.h"
-
 #include <arpa/inet.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -58,11 +44,26 @@
 #include <sys/xattr.h>
 #include <termios.h>
 #include <unistd.h>
+
 #include <memory>
 
+#include <android/log.h>
 #include <android-base/file.h>
 #include <android-base/strings.h>
 
+#include "AsynchronousCloseMonitor.h"
+#include "ExecStrings.h"
+#include "JNIHelp.h"
+#include "JniConstants.h"
+#include "JniException.h"
+#include "NetworkUtilities.h"
+#include "Portability.h"
+#include "ScopedBytes.h"
+#include "ScopedLocalRef.h"
+#include "ScopedPrimitiveArray.h"
+#include "ScopedUtfChars.h"
+#include "toStringArray.h"
+
 #ifndef __unused
 #define __unused __attribute__((__unused__))
 #endif
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 e27af69..aaf3ca1 100644
--- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -16,6 +16,14 @@
 
 #define LOG_TAG "ExpatParser"
 
+#include <expat.h>
+#include <string.h>
+
+#include <memory>
+
+#include <android/log.h>
+#include <android-base/stringprintf.h>
+
 #include "JNIHelp.h"
 #include "JniConstants.h"
 #include "JniException.h"
@@ -24,15 +32,8 @@
 #include "ScopedStringChars.h"
 #include "ScopedUtfChars.h"
 #include "jni.h"
-#include "cutils/log.h"
 #include "unicode/unistr.h"
 
-#include <memory>
-
-#include <string.h>
-#include <expat.h>
-
-#include <android-base/stringprintf.h>
 
 #define BUCKET_COUNT 128
 
diff --git a/luni/src/test/java/libcore/java/io/OldSequenceInputStreamTest.java b/luni/src/test/java/libcore/java/io/OldSequenceInputStreamTest.java
index f7d9a49..db0fbe6 100644
--- a/luni/src/test/java/libcore/java/io/OldSequenceInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/OldSequenceInputStreamTest.java
@@ -17,6 +17,8 @@
 
 package libcore.java.io;
 
+import java.io.InputStream;
+import java.util.Vector;
 import java.io.IOException;
 import java.io.SequenceInputStream;
 import tests.support.Support_ASimpleInputStream;
@@ -25,8 +27,8 @@
 
     Support_ASimpleInputStream simple1, simple2;
     SequenceInputStream si;
-    String s1 = "Hello";
-    String s2 = "World";
+    final String s1 = "Hello";
+    final String s2 = "World";
 
     public void test_available() throws IOException {
         assertEquals("Returned incorrect number of bytes!", s1.length(), si.available());
@@ -152,6 +154,54 @@
         }
     }
 
+    public void test_readStackOVerflow() throws Exception {
+        // 2^16 should be enough to overflow
+        Vector<InputStream> inputs = new Vector<>();
+        InputStream emptyInputStream = new Support_ASimpleInputStream(new byte[0]);
+        for (int i=0;i < 32768; i++) {
+            inputs.add(emptyInputStream);
+        }
+
+        SequenceInputStream sequenceInputStream = new SequenceInputStream(inputs.elements());
+        assertEquals(-1, sequenceInputStream.read());
+
+        byte[] buf = new byte[10];
+        sequenceInputStream = new SequenceInputStream(inputs.elements());
+        assertEquals(-1, sequenceInputStream.read(buf, 0, 10));
+    }
+
+    private SequenceInputStream createSequenceInputStreamWithGaps() {
+        Vector<InputStream> inputs = new Vector<>();
+        InputStream emptyInputStream = new Support_ASimpleInputStream(new byte[0]);
+        inputs.add(emptyInputStream);
+        inputs.add(simple1);
+        inputs.add(emptyInputStream);
+        inputs.add(simple2);
+        inputs.add(emptyInputStream);
+        return new SequenceInputStream(inputs.elements());
+    }
+
+    public void test_readArraySkipsEmpty() throws Exception {
+        SequenceInputStream sequenceInputStream1 = createSequenceInputStreamWithGaps();
+        byte[] buf = new byte[10];
+        assertEquals(s1.length(), sequenceInputStream1.read(buf, 0, s1.length()));
+        assertEquals(s1, new String(buf, 0, s1.length()));
+        assertEquals(s2.length(), sequenceInputStream1.read(buf, 0, s2.length()));
+        assertEquals(s2, new String(buf, 0, s2.length()));
+        assertEquals(-1, sequenceInputStream1.read(buf, 0, s1.length()));
+    }
+
+    public void test_readSkipsEmpty() throws Exception {
+        SequenceInputStream sequenceInputStream1 = createSequenceInputStreamWithGaps();
+        for (int i=0;i < s1.length(); i++) {
+            assertEquals(s1.charAt(i), sequenceInputStream1.read());
+        }
+        for (int i=0;i < s2.length(); i++) {
+            assertEquals(s2.charAt(i), sequenceInputStream1.read());
+        }
+        assertEquals(-1, sequenceInputStream1.read());
+    }
+
     protected void setUp() {
         simple1 = new Support_ASimpleInputStream(s1);
         simple2 = new Support_ASimpleInputStream(s2);
diff --git a/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java b/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
index bc4fe80..9254b8d 100644
--- a/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
+++ b/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
@@ -17,7 +17,6 @@
 package libcore.java.lang;
 
 import android.system.Os;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -38,13 +37,13 @@
 import java.util.concurrent.FutureTask;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import junit.framework.TestCase;
 import libcore.io.IoUtils;
-import libcore.java.util.AbstractResourceLeakageDetectorTestCase;
 
 import static java.lang.ProcessBuilder.Redirect.INHERIT;
 import static java.lang.ProcessBuilder.Redirect.PIPE;
 
-public class ProcessBuilderTest extends AbstractResourceLeakageDetectorTestCase {
+public class ProcessBuilderTest extends TestCase {
     private static final String TAG = ProcessBuilderTest.class.getSimpleName();
 
     private static String shell() {
diff --git a/luni/src/test/java/libcore/java/lang/reflect/ParameterTest.java b/luni/src/test/java/libcore/java/lang/reflect/ParameterTest.java
index 1a45497..18fce55 100644
--- a/luni/src/test/java/libcore/java/lang/reflect/ParameterTest.java
+++ b/luni/src/test/java/libcore/java/lang/reflect/ParameterTest.java
@@ -781,42 +781,6 @@
                 .checkGetParameterizedType("class " + outerClass.getName() + "");
     }
 
-    public void testLambdaClassConstructor() throws Exception {
-        Class<?> outerClass = ParameterTest.class;
-        Class<?> innerClass = getLambdaClassWith1ParameterConstructor();
-        Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass);
-
-        checkLambdaClassConstructor(outerClass, constructor);
-    }
-
-    private Class<?> getLambdaClassWith1ParameterConstructor() {
-        return ((Callable<?>) ParameterTest.this::outerClassMethod).getClass();
-    }
-
-    public void testLambdaClassConstructor_withMetadata() throws Exception {
-        Class<?> outerClass = loadTestOuterClassWithMetadata();
-        Object outer = outerClass.newInstance();
-        Class<?> innerClass = (Class<?>) outerClass.getDeclaredMethod(
-                "getLambdaClassWith1ParameterConstructor").invoke(outer);
-        Constructor<?> constructor = innerClass.getDeclaredConstructor(outerClass);
-
-        // There should be no parameter metadata for lambda classes.
-        checkLambdaClassConstructor(outerClass, constructor);
-    }
-
-    // This behavior is likely to be quite brittle and may not be specified.
-    private void checkLambdaClassConstructor(Class<?> outerClass, Constructor<?> constructor) {
-        ExecutableTestHelper helper = new ExecutableTestHelper(constructor);
-        helper.checkStandardParametersBehavior()
-                .checkParametersToString("[" + outerClass.getName() + " arg0]")
-                .checkParametersMetadataNotAvailable()
-                .checkParametersNoVarArgs();
-
-        helper.getParameterTestHelper(0)
-                .checkGetType(outerClass)
-                .checkGetParameterizedType("class " + outerClass.getName() + "");
-    }
-
     private static class NonIdenticalParameters {
         @SuppressWarnings("unused")
         void method0(String p0) {}
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 3f750e4..9ba2e07 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -2293,8 +2293,13 @@
         testUrlToRequestMapping("$", "$", "$");
         testUrlToUriMapping("&", "&", "&", "&", "&");
         testUrlToRequestMapping("&", "&", "&");
-        testUrlToUriMapping("'", "'", "'", "%27", "'");
-        testUrlToRequestMapping("'", "'", "%27");
+
+        // http://b/30405333 - upstream OkHttp encodes single quote (') as %27 in query parameters
+        // but this breaks iTunes remote apps: iTunes currently does not accept %27 so we have a
+        // local patch to retain the historic Android behavior of not encoding single quote.
+        testUrlToUriMapping("'", "'", "'", "'", "'");
+        testUrlToRequestMapping("'", "'", "'");
+
         testUrlToUriMapping("(", "(", "(", "(", "(");
         testUrlToRequestMapping("(", "(", "(");
         testUrlToUriMapping(")", ")", ")", ")", ")");
diff --git a/luni/src/test/java/libcore/java/nio/file/LinuxFileSystemTest.java b/luni/src/test/java/libcore/java/nio/file/LinuxFileSystemTest.java
new file mode 100644
index 0000000..4d2f4cb
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/file/LinuxFileSystemTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.nio.file;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import sun.nio.fs.LinuxFileSystemProvider;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertTrue;
+import static junit.framework.TestCase.fail;
+import static libcore.java.nio.file.LinuxFileSystemTestData.getPathExceptionTestData;
+import static libcore.java.nio.file.LinuxFileSystemTestData.getPathInputOutputTestData;
+
+@RunWith(JUnit4.class)
+public class LinuxFileSystemTest {
+
+    FileSystem fileSystem = FileSystems.getDefault();
+
+    @Test
+    public void test_provider() {
+        assertTrue(fileSystem.provider() instanceof LinuxFileSystemProvider);
+    }
+
+    @Test
+    public void test_isOpen() throws IOException {
+        assertTrue(fileSystem.isOpen());
+    }
+
+    @Test
+    public void test_close() throws IOException {
+        // Close is not supported.
+        try {
+            fileSystem.close();
+            fail();
+        } catch (UnsupportedOperationException expected) {}
+    }
+
+    @Test
+    public void test_isReadOnly() {
+        assertFalse(fileSystem.isReadOnly());
+    }
+
+    @Test
+    public void test_getSeparator() {
+        assertEquals("/", fileSystem.getSeparator());
+    }
+
+    @Test
+    public void test_getRootDirectories() {
+        Iterable<Path> rootDirectories = fileSystem.getRootDirectories();
+        Map<Path, Boolean> pathMap = new HashMap<>();
+        rootDirectories.forEach(path -> pathMap.put(path, true));
+        assertEquals(1, pathMap.size());
+        assertTrue(pathMap.get(Paths.get("/")));
+    }
+
+    @Test
+    public void test_getFileStores() {
+        Iterable<FileStore> fileStores = fileSystem.getFileStores();
+        // Asserting if the the list has non zero number stores.
+        assertTrue(fileStores.iterator().hasNext());
+    }
+
+    @Test
+    public void test_supportedFileAttributeViews() {
+        Set<String> supportedFileAttributeViewsList = fileSystem.supportedFileAttributeViews();
+        assertEquals(6, supportedFileAttributeViewsList.size());
+        assertTrue(supportedFileAttributeViewsList.contains("posix"));
+        assertTrue(supportedFileAttributeViewsList.contains("user"));
+        assertTrue(supportedFileAttributeViewsList.contains("owner"));
+        assertTrue(supportedFileAttributeViewsList.contains("unix"));
+        assertTrue(supportedFileAttributeViewsList.contains("basic"));
+        assertTrue(supportedFileAttributeViewsList.contains("dos"));
+    }
+
+    @Test
+    public void test_get() {
+        List<LinuxFileSystemTestData.TestData> inputOutputTestCases = getPathInputOutputTestData();
+        for (LinuxFileSystemTestData.TestData inputOutputTestCase : inputOutputTestCases) {
+            Assert.assertEquals(inputOutputTestCase.output, fileSystem.getPath(
+                    inputOutputTestCase.input, inputOutputTestCase.inputArray).toString());
+        }
+
+        List<LinuxFileSystemTestData.TestData> exceptionTestCases = getPathExceptionTestData();
+        for (LinuxFileSystemTestData.TestData exceptionTestCase : exceptionTestCases) {
+            try {
+                fileSystem.getPath(exceptionTestCase.input, exceptionTestCase.inputArray);
+                Assert.fail();
+            } catch (Exception expected) {
+                Assert.assertEquals(exceptionTestCase.exceptionClass, expected.getClass());
+            }
+        }
+    }
+
+    @Test
+    public void test_getPathMatcher_glob() {
+        PathMatcher pathMatcher = fileSystem.getPathMatcher("glob:" + "*.java");
+        assertTrue(pathMatcher.matches(Paths.get("f.java")));
+        assertFalse(pathMatcher.matches(Paths.get("f")));
+
+        pathMatcher = fileSystem.getPathMatcher("glob:" + "*.*");
+        assertTrue(pathMatcher.matches(Paths.get("f.t")));
+        assertFalse(pathMatcher.matches(Paths.get("f")));
+
+        pathMatcher = fileSystem.getPathMatcher("glob:" + "*.{java,class}");
+        assertTrue(pathMatcher.matches(Paths.get("f.java")));
+        assertTrue(pathMatcher.matches(Paths.get("f.class")));
+        assertFalse(pathMatcher.matches(Paths.get("f.clas")));
+        assertFalse(pathMatcher.matches(Paths.get("f.t")));
+
+        pathMatcher = fileSystem.getPathMatcher("glob:" + "f.?");
+        assertTrue(pathMatcher.matches(Paths.get("f.t")));
+        assertFalse(pathMatcher.matches(Paths.get("f.tl")));
+        assertFalse(pathMatcher.matches(Paths.get("f.")));
+
+        pathMatcher = fileSystem.getPathMatcher("glob:" + "/home/*/*");
+        assertTrue(pathMatcher.matches(Paths.get("/home/f/d")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/f/*")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/*/*")));
+        assertFalse(pathMatcher.matches(Paths.get("/home/f")));
+        assertFalse(pathMatcher.matches(Paths.get("/home/f/d/d")));
+
+        pathMatcher = fileSystem.getPathMatcher("glob:" + "/home/**");
+        assertTrue(pathMatcher.matches(Paths.get("/home/f/d")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/f/*")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/*/*")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/f")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/f/d/d")));
+        assertTrue(pathMatcher.matches(Paths.get("/home/f/d/d/d")));
+    }
+
+    @Test
+    public void test_getPathMatcher_regex() {
+        PathMatcher pathMatcher = fileSystem.getPathMatcher("regex:" + "(hello|hi)*[^a|b]?k.*");
+        assertTrue(pathMatcher.matches(Paths.get("k")));
+        assertTrue(pathMatcher.matches(Paths.get("ck")));
+        assertFalse(pathMatcher.matches(Paths.get("ak")));
+        assertTrue(pathMatcher.matches(Paths.get("kanything")));
+        assertTrue(pathMatcher.matches(Paths.get("hellohik")));
+        assertTrue(pathMatcher.matches(Paths.get("hellok")));
+        assertTrue(pathMatcher.matches(Paths.get("hellohellohellok")));
+        assertFalse(pathMatcher.matches(Paths.get("hellohellohellobk")));
+        assertFalse(pathMatcher.matches(Paths.get("hello")));
+    }
+
+    @Test
+    public void test_getPathMatcher_unsupported() {
+        try {
+            fileSystem.getPathMatcher("unsupported:test");
+            fail();
+        } catch (UnsupportedOperationException expected) {}
+    }
+
+    @Test
+    public void test_getUserPrincipalLookupService() {
+        assertNotNull(fileSystem.getUserPrincipalLookupService());
+    }
+
+    @Test
+    public void test_newWatchService() throws IOException {
+        assertNotNull(fileSystem.newWatchService());
+    }
+}
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/java/nio/file/LinuxFileSystemTestData.java b/luni/src/test/java/libcore/java/nio/file/LinuxFileSystemTestData.java
new file mode 100644
index 0000000..0780727
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/file/LinuxFileSystemTestData.java
@@ -0,0 +1,91 @@
+/*
+ * 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.nio.file;
+
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.InvalidPathException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class provides test cases to libcore.java.nio.file.PathsTest#test_get_URI,
+ * libcore.java.nio.file.PathsTest#test_get_String,
+ * libcore.java.nio.file.LinuxFileSystemTest#test_getPath
+ */
+class LinuxFileSystemTestData {
+    static List<TestData> getPathInputOutputTestData() {
+        List<TestData> inputOutputTestCases = new ArrayList<>();
+        inputOutputTestCases.add(new TestData("d1", "d1"));
+        inputOutputTestCases.add(new TestData("", ""));
+        inputOutputTestCases.add(new TestData("/", "//"));
+        inputOutputTestCases.add(new TestData("d1/d2/d3", "d1//d2/d3"));
+        inputOutputTestCases.add(new TestData("d1/d2", "d1", "", "d2"));
+        inputOutputTestCases.add(new TestData("foo", "", "foo"));
+
+        // If the name separator is "/" and getPath("/foo","bar","gus") is invoked, then the path
+        // string "/foo/bar/gus" is converted to a Path.
+        inputOutputTestCases.add(new TestData("/foo/bar/gus", "/foo", "bar", "gus"));
+        return inputOutputTestCases;
+    }
+
+    static List<TestData> getPathExceptionTestData() {
+        List<TestData> exceptionTestCases = new ArrayList<>();
+        exceptionTestCases.add(new TestData(InvalidPathException.class, "'\u0000'"));
+        exceptionTestCases.add(new TestData(NullPointerException.class, null));
+        return exceptionTestCases;
+    }
+
+    static List<TestData> getPath_URI_InputOutputTestData() {
+        // As of today, there is only one installed provider - LinuxFileSystemProvider and
+        // only scheme supported by it is "file".
+        List<TestData> inputOutputTestCases = new ArrayList<>();
+        inputOutputTestCases.add(new TestData("/d1", "file:///d1"));
+        inputOutputTestCases.add(new TestData("/", "file:///"));
+        inputOutputTestCases.add(new TestData("/d1//d2/d3", "file:///d1//d2/d3"));
+        return inputOutputTestCases;
+    }
+
+    static List<TestData> getPath_URI_ExceptionTestData() {
+        List<TestData> exceptionTestCases = new ArrayList<>();
+        exceptionTestCases.add(new TestData(IllegalArgumentException.class, "d1"));
+        exceptionTestCases.add(new TestData(FileSystemNotFoundException.class, "scheme://d"));
+        exceptionTestCases.add(new TestData(NullPointerException.class, null));
+        exceptionTestCases.add(new TestData(IllegalArgumentException.class, "file:///d#row=4"));
+        exceptionTestCases.add(new TestData(IllegalArgumentException.class, "file:///d?q=5"));
+        exceptionTestCases.add(new TestData(IllegalArgumentException.class, "file://d:5000"));
+        return exceptionTestCases;
+    }
+
+    static class TestData {
+        public String output;
+        public String input;
+        public String[] inputArray;
+        public Class exceptionClass;
+
+        TestData(String output, String input, String... inputArray) {
+            this.output = output;
+            this.input = input;
+            this.inputArray = inputArray;
+        }
+
+        TestData(Class exceptionClass, String input, String... inputArray) {
+            this.exceptionClass = exceptionClass;
+            this.input = input;
+            this.inputArray = inputArray;
+        }
+    }
+}
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/java/nio/file/PathsTest.java b/luni/src/test/java/libcore/java/nio/file/PathsTest.java
new file mode 100644
index 0000000..881d595
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/file/PathsTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.nio.file;
+
+
+import org.junit.Test;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Paths;
+import java.util.List;
+
+import static libcore.java.nio.file.LinuxFileSystemTestData.*;
+import static libcore.java.nio.file.LinuxFileSystemTestData.getPathInputOutputTestData;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class PathsTest {
+
+    @Test
+    public void test_get_String() {
+        List<TestData> inputOutputTestCases = getPathInputOutputTestData();
+        for (TestData inputOutputTestCase : inputOutputTestCases) {
+            assertEquals(inputOutputTestCase.output, Paths.get(inputOutputTestCase.input,
+                    inputOutputTestCase.inputArray).toString());
+        }
+
+        List<TestData> exceptionTestCases = getPathExceptionTestData();
+        for (TestData exceptionTestCase : exceptionTestCases) {
+            try {
+                Paths.get(exceptionTestCase.input, exceptionTestCase.inputArray);
+                fail();
+            } catch (Exception expected) {
+                assertEquals(exceptionTestCase.exceptionClass, expected.getClass());
+            }
+        }
+    }
+
+    @Test
+    public void test_get_URI() throws URISyntaxException {
+        List<TestData> inputOutputTestCases = getPath_URI_InputOutputTestData();
+        for (TestData inputOutputTestCase : inputOutputTestCases) {
+            assertEquals(inputOutputTestCase.output, Paths.get(new URI(inputOutputTestCase.input)).
+                    toString());
+        }
+
+        List<TestData> exceptionTestCases = getPath_URI_ExceptionTestData();
+        for (TestData exceptionTestCase : exceptionTestCases) {
+            try {
+                System.out.println(exceptionTestCase.input);
+                Paths.get(new URI(exceptionTestCase.input));
+                fail();
+            } catch (Exception expected) {
+                assertEquals(exceptionTestCase.exceptionClass, expected.getClass());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/java/security/AccessControllerTest.java b/luni/src/test/java/libcore/java/security/AccessControllerTest.java
index 1f7da91..5746abd 100644
--- a/luni/src/test/java/libcore/java/security/AccessControllerTest.java
+++ b/luni/src/test/java/libcore/java/security/AccessControllerTest.java
@@ -36,6 +36,7 @@
     public void testDoPrivilegedWithCombiner() {
         final Permission permission = new RuntimePermission("do stuff");
         final DomainCombiner union = new DomainCombiner() {
+            @Override
             public ProtectionDomain[] combine(ProtectionDomain[] a, ProtectionDomain[] b) {
                 throw new AssertionFailedError("Expected combiner to be unused");
             }
@@ -48,12 +49,14 @@
         final AtomicInteger actionCount = new AtomicInteger();
 
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
             public Void run() {
                 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());
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 8d1af37..055b8fe 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -16,6 +16,7 @@
 
 package libcore.java.security;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -78,6 +79,7 @@
 
     public void testSignature_getInstance_SuppliedProviderNotRegistered_Success() throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
             }
@@ -92,6 +94,7 @@
 
     public void testSignature_getInstance_DoesNotSupportKeyClass_Success() throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
                 put("Signature.FOO SupportedKeyClasses", "None");
@@ -116,6 +119,7 @@
     public void testSignature_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
                 put("Signature.FOO SupportedKeyClasses", "None");
@@ -136,6 +140,7 @@
     public void testSignature_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
             }
@@ -145,6 +150,7 @@
         try {
             {
                 Provider mockProvider2 = new MockProvider("MockProvider") {
+                    @Override
                     public void setup() {
                         put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
                     }
@@ -159,18 +165,21 @@
 
     public void testSignature_getInstance_DelayedInitialization_KeyType() throws Exception {
         Provider mockProviderSpecific = new MockProvider("MockProviderSpecific") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.SpecificKeyTypes.class.getName());
                 put("Signature.FOO SupportedKeyClasses", MockPrivateKey.class.getName());
             }
         };
         Provider mockProviderSpecific2 = new MockProvider("MockProviderSpecific2") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.SpecificKeyTypes2.class.getName());
                 put("Signature.FOO SupportedKeyClasses", MockPrivateKey2.class.getName());
             }
         };
         Provider mockProviderAll = new MockProvider("MockProviderAll") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
             }
@@ -422,6 +431,7 @@
 
     public void testSignature_getProvider_Subclass() throws Exception {
         Provider mockProviderNonSpi = new MockProvider("MockProviderNonSpi") {
+            @Override
             public void setup() {
                 put("Signature.FOO", MySignature.class.getName());
             }
@@ -2874,7 +2884,8 @@
         Signature sig = Signature.getInstance("NONEwithRSA");
         sig.initVerify(pubKey);
         sig.update(Vector1Data);
-        assertFalse("Invalid signature must not verify", sig.verify("Invalid".getBytes()));
+        assertFalse("Invalid signature must not verify",
+                sig.verify("Invalid".getBytes(UTF_8)));
     }
 
     public void testSign_NONEwithRSA_Key_DataTooLarge_Failure() throws Exception {
@@ -2973,7 +2984,8 @@
         sig.initVerify(pubKey);
         sig.update(Vector1Data);
 
-        assertFalse("Invalid signature should not verify", sig.verify("Invalid sig".getBytes()));
+        assertFalse("Invalid signature should not verify",
+                sig.verify("Invalid sig".getBytes(UTF_8)));
     }
 
     public void testVerify_NONEwithRSA_Key_SignatureTooLarge_Failure() throws Exception {
@@ -3299,13 +3311,13 @@
 
         Signature ecdsaVerify = Signature.getInstance("SHA1withECDSA");
         ecdsaVerify.initVerify(pub);
-        ecdsaVerify.update("Satoshi Nakamoto".getBytes("UTF-8"));
+        ecdsaVerify.update("Satoshi Nakamoto".getBytes(UTF_8));
         boolean result = ecdsaVerify.verify(SIGNATURE);
         assertEquals(true, result);
 
         ecdsaVerify = Signature.getInstance("SHA1withECDSA");
         ecdsaVerify.initVerify(pub);
-        ecdsaVerify.update("Not Satoshi Nakamoto".getBytes("UTF-8"));
+        ecdsaVerify.update("Not Satoshi Nakamoto".getBytes(UTF_8));
         result = ecdsaVerify.verify(SIGNATURE);
         assertEquals(false, result);
     }
diff --git a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
index a3a721a..7b82cc6 100644
--- a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java
@@ -16,6 +16,8 @@
 
 package libcore.java.security.cert;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import com.android.org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
 import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
 import com.android.org.bouncycastle.asn1.x509.Extension;
@@ -50,6 +52,7 @@
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.List;
 import java.util.TimeZone;
 
@@ -103,7 +106,7 @@
             + "-----END CERTIFICATE-----\r\n";
 
     private static final byte[] VALID_CERTIFICATE_PEM_HEADER = "-----BEGIN CERTIFICATE-----\n"
-            .getBytes();
+            .getBytes(UTF_8);
 
     private static final byte[] VALID_CERTIFICATE_PEM_DATA =
              ("MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM"
@@ -122,10 +125,10 @@
             + "ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF"
             + "AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5"
             + "u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6"
-            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==").getBytes();
+            + "z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==").getBytes(UTF_8);
 
     private static final byte[] VALID_CERTIFICATE_PEM_FOOTER = "\n-----END CERTIFICATE-----\n"
-            .getBytes();
+            .getBytes(UTF_8);
 
     private static final String INVALID_CERTIFICATE_PEM =
             "-----BEGIN CERTIFICATE-----\n"
@@ -183,19 +186,19 @@
 
     private void test_generateCertificate(CertificateFactory cf) throws Exception {
         {
-            byte[] valid = VALID_CERTIFICATE_PEM.getBytes();
+            byte[] valid = VALID_CERTIFICATE_PEM.getBytes(UTF_8);
             Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
             assertNotNull(c);
         }
 
         {
-            byte[] valid = VALID_CERTIFICATE_PEM_CRLF.getBytes();
+            byte[] valid = VALID_CERTIFICATE_PEM_CRLF.getBytes(UTF_8);
             Certificate c = cf.generateCertificate(new ByteArrayInputStream(valid));
             assertNotNull(c);
         }
 
         try {
-            byte[] invalid = INVALID_CERTIFICATE_PEM.getBytes();
+            byte[] invalid = INVALID_CERTIFICATE_PEM.getBytes(UTF_8);
             cf.generateCertificate(new ByteArrayInputStream(invalid));
             fail();
         } catch (CertificateException expected) {
@@ -263,7 +266,7 @@
             throws Exception {
         try {
             Certificate c = cf.generateCertificate(new ByteArrayInputStream(
-                    "-----BEGIN CERTIFICATE-----".getBytes()));
+                    "-----BEGIN CERTIFICATE-----".getBytes(UTF_8)));
             if (!"BC".equals(cf.getProvider().getName())) {
                 fail("should throw CertificateException: " + cf.getProvider().getName());
             }
@@ -277,7 +280,7 @@
 
     private void test_generateCertificate_InputStream_Offset_Correct(CertificateFactory cf)
             throws Exception {
-        byte[] valid = VALID_CERTIFICATE_PEM.getBytes();
+        byte[] valid = VALID_CERTIFICATE_PEM.getBytes(UTF_8);
 
         byte[] doubleCertificateData = new byte[valid.length * 2];
         System.arraycopy(valid, 0, doubleCertificateData, 0, valid.length);
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
index 817ad28..7178a59 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java
@@ -16,6 +16,8 @@
 
 package libcore.java.security.cert;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import sun.security.provider.X509Factory;
 import sun.security.x509.X509CRLImpl;
 import tests.support.resource.Support_Resources;
@@ -30,7 +32,6 @@
 import java.security.InvalidKeyException;
 import java.security.Provider;
 import java.security.Security;
-import java.security.SignatureException;
 import java.security.cert.CRL;
 import java.security.cert.CRLReason;
 import java.security.cert.CertificateFactory;
@@ -129,7 +130,7 @@
         final InputStream ris = Support_Resources.getStream(name);
         try {
 
-            final BufferedReader buf = new BufferedReader(new InputStreamReader(ris));
+            final BufferedReader buf = new BufferedReader(new InputStreamReader(ris, UTF_8));
 
             String line;
             while ((line = buf.readLine()) != null) {
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
index f1cd4ff..0b01541 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java
@@ -16,7 +16,7 @@
 
 package libcore.java.security.cert;
 
-import tests.support.resource.Support_Resources;
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
@@ -56,11 +56,10 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
-
 import javax.security.auth.x500.X500Principal;
-
 import junit.framework.TestCase;
 import libcore.java.security.StandardNames;
+import tests.support.resource.Support_Resources;
 
 public class X509CertificateTest extends TestCase {
     private Provider[] mX509Providers;
@@ -173,7 +172,7 @@
             final SimpleDateFormat sdf =
                     new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz", Locale.US);
 
-            final BufferedReader buf = new BufferedReader(new InputStreamReader(ris));
+            final BufferedReader buf = new BufferedReader(new InputStreamReader(ris, UTF_8));
             String line = buf.readLine();
             int index = line.indexOf('=');
             assertEquals("notBefore", line.substring(0, index));
@@ -199,7 +198,7 @@
     private BigInteger getRsaCertificateSerial() throws Exception {
         final InputStream ris = Support_Resources.getStream("x509/cert-rsa-serial.txt");
         try {
-            final BufferedReader buf = new BufferedReader(new InputStreamReader(ris));
+            final BufferedReader buf = new BufferedReader(new InputStreamReader(ris, UTF_8));
 
             String line = buf.readLine();
             int index = line.indexOf('=');
diff --git a/luni/src/test/java/libcore/java/text/DateFormatTest.java b/luni/src/test/java/libcore/java/text/DateFormatTest.java
new file mode 100644
index 0000000..8e215ab
--- /dev/null
+++ b/luni/src/test/java/libcore/java/text/DateFormatTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.text;
+
+import junit.framework.TestCase;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class DateFormatTest extends TestCase {
+
+    // Regression test for http://b/31762542. If this test fails it implies that changes to
+    // DateFormat.is24Hour will not be effective.
+    public void testIs24Hour_notCached() throws Exception {
+        Boolean originalIs24Hour = DateFormat.is24Hour;
+        try {
+            // These tests hardcode expectations for Locale.US.
+            DateFormat.is24Hour = null; // null == locale default (12 hour for US)
+            checkTimePattern(DateFormat.SHORT, "h:mm a");
+            checkTimePattern(DateFormat.MEDIUM, "h:mm:ss a");
+
+            DateFormat.is24Hour = true; // Explicit 24 hour.
+            checkTimePattern(DateFormat.SHORT, "HH:mm");
+            checkTimePattern(DateFormat.MEDIUM, "HH:mm:ss");
+
+            DateFormat.is24Hour = false; // Explicit 12 hour.
+            checkTimePattern(DateFormat.SHORT, "h:mm a");
+            checkTimePattern(DateFormat.MEDIUM, "h:mm:ss a");
+        } finally {
+            DateFormat.is24Hour = originalIs24Hour;
+        }
+    }
+
+    private static void checkTimePattern(int style, String expectedPattern) {
+        final Locale locale = Locale.US;
+        final Date current = new Date(1468250177000L); // 20160711 15:16:17 GMT
+        DateFormat format = DateFormat.getTimeInstance(style, locale);
+        String actualDateString = format.format(current);
+        SimpleDateFormat sdf = new SimpleDateFormat(expectedPattern, locale);
+        String expectedDateString = sdf.format(current);
+        assertEquals(expectedDateString, actualDateString);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java b/luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java
deleted file mode 100644
index 5ea67d3..0000000
--- a/luni/src/test/java/libcore/java/util/AbstractResourceLeakageDetectorTestCase.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.java.util;
-
-import junit.framework.TestCase;
-
-/**
- * Ensures that resources used within a test are cleaned up; will detect problems with tests and
- * also with runtime.
- */
-public abstract class AbstractResourceLeakageDetectorTestCase extends TestCase {
-  /**
-   * The leakage detector.
-   */
-  private ResourceLeakageDetector detector;
-
-  @Override
-  protected void setUp() throws Exception {
-    detector = ResourceLeakageDetector.newDetector();
-  }
-
-  @Override
-  protected void tearDown() throws Exception {
-    // If available check for resource leakage. At this point it is impossible to determine
-    // whether the test has thrown an exception. If it has then the exception thrown by this
-    // could hide that test failure; it largely depends on the test runner.
-    if (detector != null) {
-      detector.checkForLeaks();
-    }
-  }
-}
diff --git a/luni/src/test/java/libcore/java/util/CurrencyTest.java b/luni/src/test/java/libcore/java/util/CurrencyTest.java
index 91584de..552ad9e 100644
--- a/luni/src/test/java/libcore/java/util/CurrencyTest.java
+++ b/luni/src/test/java/libcore/java/util/CurrencyTest.java
@@ -18,14 +18,10 @@
 
 import java.util.Currency;
 import java.util.Locale;
-import java.util.Objects;
 import java.util.Set;
 
 import libcore.util.SerializationTester;
 
-import static java.util.Locale.Category.DISPLAY;
-import static java.util.Locale.Category.FORMAT;
-
 public class CurrencyTest extends junit.framework.TestCase {
     // Regression test to ensure that Currency.getSymbol(Locale) returns the
     // currency code if ICU doesn't have a localization of the symbol. The
@@ -53,13 +49,12 @@
      */
     public void test_getSymbol_noLocaleArgument() {
         Currency currency = Currency.getInstance("DEM");
-        Locales locales = getDefaultLocales();
+        Locales locales = Locales.getAndSetDefaultForTest(Locale.US, Locale.GERMANY, Locale.FRANCE);
         try {
-            // Locales(locale, displayLocale, formatLocale)
-            setDefaultLocales(new Locales(Locale.US, Locale.GERMANY, Locale.FRANCE));
+            // getAndSetDefaultForTest(uncategorizedLocale, displayLocale, formatLocale)
             assertEquals("DM", currency.getSymbol());
         } finally {
-            setDefaultLocales(locales);
+            locales.setAsDefault();
         }
     }
 
@@ -115,13 +110,12 @@
      */
     public void test_getDisplayName_noLocaleArgument() {
         Currency currency = Currency.getInstance("DEM");
-        Locales locales = getDefaultLocales();
+        // getAndSetDefaultForTest(uncategorizedLocale, displayLocale, formatLocale)
+        Locales locales = Locales.getAndSetDefaultForTest(Locale.US, Locale.GERMANY, Locale.FRANCE);
         try {
-            // Locales(uncategorizedLocale, displayLocale, formatLocale)
-            setDefaultLocales(new Locales(Locale.US, Locale.GERMANY, Locale.FRANCE));
             assertEquals("Deutsche Mark", currency.getDisplayName());
         } finally {
-            setDefaultLocales(locales);
+            locales.setAsDefault();
         }
     }
 
@@ -171,53 +165,4 @@
         assertEquals(0, Currency.getInstance("XFU").getNumericCode());
     }
 
-    static Locales getDefaultLocales() {
-        return new Locales(
-                Locale.getDefault(), Locale.getDefault(DISPLAY), Locale.getDefault(FORMAT));
-    }
-
-    static void setDefaultLocales(Locales locales) {
-        // The lines below must set the Locales in this order because setDefault(Locale)
-        // overwrites the other ones.
-        Locale.setDefault(locales.uncategorizedLocale);
-        Locale.setDefault(DISPLAY, locales.displayLocale);
-        Locale.setDefault(FORMAT, locales.formatLocale);
-
-        assertEquals(locales, getDefaultLocales()); // sanity check
-    }
-
-    static class Locales {
-        final Locale uncategorizedLocale;
-        final Locale displayLocale;
-        final Locale formatLocale;
-
-        public Locales(Locale uncategorizedLocale, Locale displayLocale, Locale formatLocale) {
-            this.uncategorizedLocale = uncategorizedLocale;
-            this.displayLocale = displayLocale;
-            this.formatLocale = formatLocale;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof Locales)) {
-                return false;
-            }
-            Locales that = (Locales) obj;
-            return uncategorizedLocale.equals(that.uncategorizedLocale)
-                    && displayLocale.equals(that.displayLocale)
-                    && formatLocale.equals(that.formatLocale);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(uncategorizedLocale, displayLocale, formatLocale);
-        }
-
-        @Override
-        public String toString() {
-            return "Locales[displayLocale=" + displayLocale + ", locale=" + uncategorizedLocale +
-                    ", formatLocale=" + formatLocale + ']';
-        }
-    }
-
 }
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index f9146b3..91af1b7 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -29,6 +29,31 @@
 import java.util.MissingResourceException;
 
 public class LocaleTest extends junit.framework.TestCase {
+
+    public void test_extension_absent() throws Exception {
+        Locale locale = Locale.forLanguageTag("en-US");
+        assertFalse(locale.hasExtensions());
+        assertEquals(locale, locale.stripExtensions());
+    }
+
+    public void test_extension_builder() throws Exception {
+        Locale.Builder b = new Locale.Builder();
+        Locale localeWithoutExtension = b.build();
+        b.setExtension('g', "FO_ba-BR_bg");
+        Locale locale = b.build();
+        assertTrue(locale.hasExtensions());
+        assertFalse(locale.stripExtensions().hasExtensions());
+        assertEquals(localeWithoutExtension, locale.stripExtensions());
+    }
+
+    public void test_extension_languageTag() throws Exception {
+        Locale lA = Locale.forLanguageTag("en-Latn-US-x-foo");
+        Locale lB = Locale.forLanguageTag("en-Latn-US");
+        assertTrue(lA.hasExtensions());
+        assertFalse(lB.hasExtensions());
+        assertEquals(lB, lA.stripExtensions());
+    }
+
     // http://b/2611311; if there's no display language/country/variant, use the raw codes.
     public void test_getDisplayName_invalid() throws Exception {
         Locale invalid = new Locale("AaBbCc", "DdEeFf", "GgHhIi");
@@ -774,22 +799,27 @@
 
         Locale l = b.build();
 
-        // getDisplayScript() test relies on the default locale. We set it here to avoid test
-        // failures if the test device is set to a non-English locale.
-        Locale.setDefault(Locale.US);
-        assertEquals("Latin", l.getDisplayScript());
+        // getAndSetDefaultForTest(uncategorizedLocale, displayLocale, formatLocale)
+        Locales locales = Locales.getAndSetDefaultForTest(Locale.US, Locale.GERMANY, Locale.FRANCE);
+        try {
+            // Check that getDisplayScript() uses the default DISPLAY Locale.
+            assertEquals("Lateinisch", l.getDisplayScript()); // the German word for "Latin"
 
-        assertEquals("Lateinisch", l.getDisplayScript(Locale.GERMAN));
-        // Fallback for navajo, a language for which we don't have data.
-        assertEquals("Latin", l.getDisplayScript(new Locale("nv", "US")));
+            assertEquals("latino", l.getDisplayScript(Locale.ITALY));
 
-        b= new Locale.Builder();
-        b.setLanguage("en").setRegion("US").setScript("Fooo");
+            // Fallback for navajo, a language for which we don't have data.
+            assertEquals("Latin", l.getDisplayScript(new Locale("nv", "US")));
 
-        // Will be equivalent to getScriptCode for scripts that aren't
-        // registered with ISO-15429 (but are otherwise well formed).
-        l = b.build();
-        assertEquals("Fooo", l.getDisplayScript());
+            b = new Locale.Builder();
+            b.setLanguage("en").setRegion("US").setScript("Fooo");
+
+            // Will be equivalent to getScriptCode for scripts that aren't
+            // registered with ISO-15429 (but are otherwise well formed).
+            l = b.build();
+            assertEquals("Fooo", l.getDisplayScript());
+        } finally {
+            locales.setAsDefault();
+        }
     }
 
     public void test_setLanguageTag_malformedTags() {
@@ -1254,6 +1284,7 @@
     public void test_setDefault_withCategory() {
         final Locale defaultLocale = Locale.getDefault();
         try {
+            // Establish a baseline for the checks further down
             Locale.setDefault(Locale.US);
             assertEquals(Locale.US, Locale.getDefault(Locale.Category.FORMAT));
             assertEquals(Locale.US, Locale.getDefault(Locale.Category.DISPLAY));
@@ -1273,6 +1304,12 @@
             assertEquals(Locale.FRANCE, Locale.getDefault(Locale.Category.FORMAT));
             assertEquals(Locale.FRANCE, Locale.getDefault(Locale.Category.DISPLAY));
             assertEquals(Locale.FRANCE, Locale.getDefault());
+
+            // Check that setDefault(Locale) sets all three defaults
+            Locale.setDefault(Locale.US);
+            assertEquals(Locale.US, Locale.getDefault(Locale.Category.FORMAT));
+            assertEquals(Locale.US, Locale.getDefault(Locale.Category.DISPLAY));
+            assertEquals(Locale.US, Locale.getDefault());
         } finally {
             Locale.setDefault(defaultLocale);
         }
diff --git a/luni/src/test/java/libcore/java/util/Locales.java b/luni/src/test/java/libcore/java/util/Locales.java
new file mode 100644
index 0000000..102188b
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/Locales.java
@@ -0,0 +1,102 @@
+/*
+ * 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.Locale;
+import java.util.Objects;
+
+import static java.util.Locale.Category.DISPLAY;
+import static java.util.Locale.Category.FORMAT;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Helper class for tests that need to temporarily change the default Locales.
+ */
+class Locales {
+    private final Locale uncategorizedLocale;
+    private final Locale displayLocale;
+    private final Locale formatLocale;
+
+    private Locales(Locale uncategorizedLocale, Locale displayLocale, Locale formatLocale) {
+        this.uncategorizedLocale = uncategorizedLocale;
+        this.displayLocale = displayLocale;
+        this.formatLocale = formatLocale;
+    }
+
+    /**
+     * Sets the specified default Locale, default DISPLAY Locale and default FORMAT Locale.
+     * Every call to this method should be paired with exactly one corresponding call to
+     * reset the previous values:
+     * <pre>
+     *     Locales locales = Locales.getAndSetDefaultForTest(Locale.US, Locale.CHINA, Locale.UK);
+     *     try {
+     *         ...
+     *     } finally {
+     *         locales.setAsDefault();
+     *     }
+     * </pre>
+     */
+    public static Locales getAndSetDefaultForTest(Locale uncategorizedLocale, Locale displayLocale,
+            Locale formatLocale) {
+        Locales oldLocales = getDefault();
+        Locales newLocales = new Locales(uncategorizedLocale, displayLocale, formatLocale);
+        newLocales.setAsDefault();
+        assertEquals(newLocales, getDefault()); // sanity check
+        return oldLocales;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Locales)) {
+            return false;
+        }
+        Locales that = (Locales) obj;
+        return uncategorizedLocale.equals(that.uncategorizedLocale)
+                && displayLocale.equals(that.displayLocale)
+                && formatLocale.equals(that.formatLocale);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(uncategorizedLocale, displayLocale, formatLocale);
+    }
+
+    @Override
+    public String toString() {
+        return "Locales[displayLocale=" + displayLocale + ", locale=" + uncategorizedLocale +
+                ", formatLocale=" + formatLocale + ']';
+    }
+
+    /**
+     * Reset the system's default Locale values to what they were when this
+     * Locales was obtained.
+     */
+    public void setAsDefault() {
+        // The lines below must set the Locales in this order because setDefault(Locale)
+        // overwrites the other ones.
+        Locale.setDefault(uncategorizedLocale);
+        Locale.setDefault(DISPLAY, displayLocale);
+        Locale.setDefault(FORMAT, formatLocale);
+    }
+
+    public static Locales getDefault() {
+        return new Locales(
+                Locale.getDefault(), Locale.getDefault(DISPLAY), Locale.getDefault(FORMAT));
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java b/luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java
deleted file mode 100644
index 954665a..0000000
--- a/luni/src/test/java/libcore/java/util/ResourceLeakageDetector.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.java.util;
-
-/**
- * Detects resource leakages for resources that are protected by <code>CloseGuard</code> mechanism.
- *
- * <p>If multiple instances of this are active at the same time, i.e. have been created but not yet
- * had their {@link #checkForLeaks()} method called then while they will report all the leakages
- * detected they may report the leakages caused by the code being tested by another detector.
- *
- * <p>The underlying CloseGuardMonitor is loaded using reflection to ensure that this will run,
- * albeit doing nothing, on the reference implementation.
- */
-public class ResourceLeakageDetector {
-  /** The class for the CloseGuardMonitor, null if not supported. */
-  private static final Class<?> CLOSE_GUARD_MONITOR_CLASS;
-
-  static {
-    ClassLoader classLoader = ResourceLeakageDetector.class.getClassLoader();
-    Class<?> clazz;
-    try {
-      // Make sure that the CloseGuard class exists; this ensures that this is not running
-      // on a RI JVM.
-      classLoader.loadClass("dalvik.system.CloseGuard");
-
-      // Load the monitor class for later instantiation.
-      clazz = classLoader.loadClass("dalvik.system.CloseGuardMonitor");
-
-    } catch (ClassNotFoundException e) {
-      System.err.println("Resource leakage will not be detected; "
-          + "this is expected in the reference implementation");
-      e.printStackTrace(System.err);
-
-      // Ignore, probably running in reference implementation.
-      clazz = null;
-    }
-
-    CLOSE_GUARD_MONITOR_CLASS = clazz;
-  }
-
-  /**
-   * The underlying CloseGuardMonitor that will perform the post test checks for resource
-   * leakage.
-   */
-  private Runnable postTestChecker;
-
-  /**
-   * Create a new detector.
-   *
-   * @return The new {@link ResourceLeakageDetector}, its {@link #checkForLeaks()} method must be
-   * called otherwise it will not clean up properly after itself.
-   */
-  public static ResourceLeakageDetector newDetector()
-      throws Exception {
-    return new ResourceLeakageDetector();
-  }
-
-  private ResourceLeakageDetector()
-      throws Exception {
-    if (CLOSE_GUARD_MONITOR_CLASS != null) {
-      postTestChecker = (Runnable) CLOSE_GUARD_MONITOR_CLASS.newInstance();
-    }
-  }
-
-  /**
-   * Detect any leaks that have arisen since this was created.
-   *
-   * @throws Exception If any leaks were detected.
-   */
-  public void checkForLeaks() throws Exception {
-    // If available check for resource leakage.
-    if (postTestChecker != null) {
-      postTestChecker.run();
-    }
-  }
-}
diff --git a/luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java b/luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java
deleted file mode 100644
index 5509f73..0000000
--- a/luni/src/test/java/libcore/java/util/ResourceLeakageDetectorTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package libcore.java.util;
-
-import dalvik.system.CloseGuard;
-import junit.framework.TestCase;
-
-/**
- * Test for {@link ResourceLeakageDetector}
- */
-public class ResourceLeakageDetectorTest extends TestCase {
-  /**
-   * This test will not work on RI as it does not support the <code>CloseGuard</code> or similar
-   * mechanism.
-   */
-  // TODO(paulduffin): b/31542223 - Work out why this is failing in CTS, fix and reenable.
-  public void notestDetectsUnclosedCloseGuard() throws Exception {
-    ResourceLeakageDetector detector = ResourceLeakageDetector.newDetector();
-    try {
-      CloseGuard closeGuard = createCloseGuard();
-      closeGuard.open("open");
-    } finally {
-      boolean leaksDetected = true;
-      try {
-        System.logI("Checking for leaks");
-        detector.checkForLeaks();
-        leaksDetected = false;
-      } catch (AssertionError expected) {
-        // The leak detector should throw this error.
-      }
-
-      if (!leaksDetected) {
-        fail("Did not detect any leaks");
-      }
-    }
-  }
-
-  public void testIgnoresClosedCloseGuard() throws Exception {
-    ResourceLeakageDetector detector = ResourceLeakageDetector.newDetector();
-    try {
-      CloseGuard closeGuard = createCloseGuard();
-      closeGuard.open("open");
-      closeGuard.close();
-    } finally {
-      detector.checkForLeaks();
-    }
-  }
-
-  /**
-   * Private method to ensure that the CloseGuard object is garbage collected.
-   */
-  private CloseGuard createCloseGuard() {
-    final CloseGuard closeGuard = CloseGuard.get();
-    new Object() {
-      @Override
-      protected void finalize() throws Throwable {
-        try {
-          closeGuard.warnIfOpen();
-        } finally {
-          super.finalize();
-        }
-      }
-    };
-
-    return closeGuard;
-  }
-}
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index c5260328..ed5fdfb 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -406,6 +406,21 @@
             setExpectedBlockSize("RSA", Cipher.DECRYPT_MODE, 256);
             setExpectedBlockSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
             setExpectedBlockSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 256);
+
+            // OAEP padding modes change the output and block size. SHA-1 is the default.
+            setExpectedBlockSize("RSA/ECB/OAEPPadding", Cipher.ENCRYPT_MODE, 214);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.ENCRYPT_MODE, 214);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.ENCRYPT_MODE, 198);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.ENCRYPT_MODE, 190);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.ENCRYPT_MODE, 158);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.ENCRYPT_MODE, 126);
+
+            setExpectedBlockSize("RSA/ECB/OAEPPadding", Cipher.DECRYPT_MODE, 256);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
+            setExpectedBlockSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.DECRYPT_MODE, 256);
         }
     }
 
@@ -614,6 +629,7 @@
         setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, 256);
         setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, 256);
         setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, 245);
+        setExpectedOutputSize("RSA/ECB/OAEPPadding", Cipher.DECRYPT_MODE, 256);
 
         // SunJCE returns the full for size even when PKCS1Padding is specified
         setExpectedOutputSize("RSA/ECB/PKCS1Padding", Cipher.DECRYPT_MODE, "SunJCE", 256);
@@ -621,6 +637,21 @@
         // BC strips the leading 0 for us even when NoPadding is specified
         setExpectedOutputSize("RSA", Cipher.DECRYPT_MODE, "BC", 255);
         setExpectedOutputSize("RSA/ECB/NoPadding", Cipher.DECRYPT_MODE, "BC", 255);
+
+        // OAEP padding modes change the output and block size. SHA-1 is the default.
+        setExpectedOutputSize("RSA/ECB/OAEPPadding", Cipher.DECRYPT_MODE, 214);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.DECRYPT_MODE, 214);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.DECRYPT_MODE, 198);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.DECRYPT_MODE, 190);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.DECRYPT_MODE, 158);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.DECRYPT_MODE, 126);
+
+        setExpectedOutputSize("RSA/ECB/OAEPPadding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
+        setExpectedOutputSize("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", Cipher.ENCRYPT_MODE, 256);
     }
 
     private static void setExpectedOutputSize(String algorithm, int value) {
@@ -2315,6 +2346,55 @@
     };
 
     /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha1 -pkeyopt rsa_oaep_label:010203FFA00A | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA256_MGF1_SHA1_LABEL = new byte[] {
+            (byte) 0x80, (byte) 0xb1, (byte) 0xf2, (byte) 0xc2, (byte) 0x03, (byte) 0xc5,
+            (byte) 0xdf, (byte) 0xbd, (byte) 0xed, (byte) 0xfe, (byte) 0xe6, (byte) 0xff,
+            (byte) 0xd3, (byte) 0x38, (byte) 0x1e, (byte) 0x6d, (byte) 0xae, (byte) 0x47,
+            (byte) 0xfe, (byte) 0x19, (byte) 0xf9, (byte) 0x8c, (byte) 0xf1, (byte) 0x4d,
+            (byte) 0x18, (byte) 0x2b, (byte) 0x7e, (byte) 0x8e, (byte) 0x47, (byte) 0x39,
+            (byte) 0xa8, (byte) 0x04, (byte) 0xc4, (byte) 0x7d, (byte) 0x56, (byte) 0x03,
+            (byte) 0x15, (byte) 0x92, (byte) 0x18, (byte) 0xde, (byte) 0x56, (byte) 0xb3,
+            (byte) 0x01, (byte) 0x93, (byte) 0x16, (byte) 0xe3, (byte) 0xfa, (byte) 0xaa,
+            (byte) 0xf3, (byte) 0x73, (byte) 0x39, (byte) 0x26, (byte) 0xfb, (byte) 0xb0,
+            (byte) 0x18, (byte) 0x20, (byte) 0xdb, (byte) 0xa1, (byte) 0xbf, (byte) 0x31,
+            (byte) 0x22, (byte) 0xc8, (byte) 0x1d, (byte) 0xdb, (byte) 0xa0, (byte) 0x5a,
+            (byte) 0x22, (byte) 0xcd, (byte) 0x09, (byte) 0xb3, (byte) 0xcb, (byte) 0xa2,
+            (byte) 0x46, (byte) 0x14, (byte) 0x35, (byte) 0x66, (byte) 0xe8, (byte) 0xb8,
+            (byte) 0x07, (byte) 0x23, (byte) 0xc5, (byte) 0xae, (byte) 0xe6, (byte) 0xf1,
+            (byte) 0x7a, (byte) 0x8f, (byte) 0x5c, (byte) 0x44, (byte) 0x34, (byte) 0xbf,
+            (byte) 0xd6, (byte) 0xf8, (byte) 0x0c, (byte) 0xc7, (byte) 0x8d, (byte) 0xcd,
+            (byte) 0x23, (byte) 0x84, (byte) 0xbe, (byte) 0x9b, (byte) 0xbf, (byte) 0x9a,
+            (byte) 0x70, (byte) 0x0f, (byte) 0x18, (byte) 0xc0, (byte) 0x6f, (byte) 0x23,
+            (byte) 0x67, (byte) 0xf8, (byte) 0xbb, (byte) 0xce, (byte) 0xc2, (byte) 0x47,
+            (byte) 0x82, (byte) 0xa0, (byte) 0xa5, (byte) 0x60, (byte) 0xcd, (byte) 0x25,
+            (byte) 0xa5, (byte) 0x4b, (byte) 0xe4, (byte) 0x06, (byte) 0x7f, (byte) 0x46,
+            (byte) 0x62, (byte) 0x86, (byte) 0x94, (byte) 0xbc, (byte) 0x7f, (byte) 0xb0,
+            (byte) 0x2e, (byte) 0xc1, (byte) 0x8c, (byte) 0x6c, (byte) 0x58, (byte) 0x05,
+            (byte) 0x6f, (byte) 0x35, (byte) 0x76, (byte) 0xd3, (byte) 0xdf, (byte) 0xc0,
+            (byte) 0xdd, (byte) 0x66, (byte) 0xbe, (byte) 0xa1, (byte) 0x7e, (byte) 0x52,
+            (byte) 0xed, (byte) 0x81, (byte) 0x0e, (byte) 0x2d, (byte) 0x5b, (byte) 0x2b,
+            (byte) 0xe3, (byte) 0x52, (byte) 0x0e, (byte) 0x56, (byte) 0x9b, (byte) 0x05,
+            (byte) 0x72, (byte) 0xa8, (byte) 0xc8, (byte) 0x57, (byte) 0x22, (byte) 0x67,
+            (byte) 0x0e, (byte) 0x5f, (byte) 0x01, (byte) 0xf2, (byte) 0x69, (byte) 0x66,
+            (byte) 0x6a, (byte) 0x47, (byte) 0x4f, (byte) 0x78, (byte) 0xb3, (byte) 0x1e,
+            (byte) 0x7d, (byte) 0xce, (byte) 0xb3, (byte) 0x35, (byte) 0xdf, (byte) 0x23,
+            (byte) 0xac, (byte) 0xf8, (byte) 0x88, (byte) 0xa1, (byte) 0xde, (byte) 0x38,
+            (byte) 0x96, (byte) 0xfd, (byte) 0xa2, (byte) 0x5d, (byte) 0x09, (byte) 0x52,
+            (byte) 0x11, (byte) 0x2b, (byte) 0x21, (byte) 0xf0, (byte) 0x0d, (byte) 0x4c,
+            (byte) 0x15, (byte) 0xc3, (byte) 0x88, (byte) 0x2b, (byte) 0xf6, (byte) 0x2b,
+            (byte) 0xe3, (byte) 0xfd, (byte) 0x52, (byte) 0xf0, (byte) 0x09, (byte) 0x5c,
+            (byte) 0x4f, (byte) 0x5b, (byte) 0x8b, (byte) 0x84, (byte) 0x71, (byte) 0x72,
+            (byte) 0x8d, (byte) 0xaa, (byte) 0x6c, (byte) 0x55, (byte) 0xba, (byte) 0xe7,
+            (byte) 0x9c, (byte) 0xba, (byte) 0xbf, (byte) 0xf4, (byte) 0x09, (byte) 0x0a,
+            (byte) 0x60, (byte) 0xec, (byte) 0x53, (byte) 0xa4, (byte) 0x01, (byte) 0xa5,
+            (byte) 0xf2, (byte) 0x58, (byte) 0xab, (byte) 0x95, (byte) 0x68, (byte) 0x79,
+            (byte) 0x0b, (byte) 0xc3, (byte) 0xc4, (byte) 0x00, (byte) 0x68, (byte) 0x19,
+            (byte) 0xca, (byte) 0x07, (byte) 0x0d, (byte) 0x32
+    };
+
+    /*
      * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey rsakey.pem \
      * -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha224 -pkeyopt rsa_mgf1_md:sha224 \
      * | xxd -p -i | sed 's/0x/(byte) 0x/g'
@@ -2518,6 +2598,55 @@
             (byte) 0x9e, (byte) 0x77, (byte) 0xe0, (byte) 0xaa
     };
 
+    /*
+     * echo -n 'This is a test of OAEP' | openssl pkeyutl -encrypt -inkey /tmp/rsakey.txt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha512 -pkeyopt rsa_mgf1_md:sha512 -pkeyopt rsa_oaep_label:010203FFA00A | xxd -p -i | sed 's/0x/(byte) 0x/g'
+     */
+    public static final byte[] RSA_Vector2_OAEP_SHA512_MGF1_SHA512_LABEL = new byte[] {
+            (byte) 0x31, (byte) 0x3b, (byte) 0x23, (byte) 0xcf, (byte) 0x40, (byte) 0xfe,
+            (byte) 0x15, (byte) 0x94, (byte) 0xd6, (byte) 0x81, (byte) 0x21, (byte) 0x69,
+            (byte) 0x8e, (byte) 0x58, (byte) 0xd5, (byte) 0x0f, (byte) 0xa8, (byte) 0x72,
+            (byte) 0x94, (byte) 0x13, (byte) 0xfe, (byte) 0xf9, (byte) 0xa1, (byte) 0x47,
+            (byte) 0x49, (byte) 0x91, (byte) 0xcb, (byte) 0x66, (byte) 0xe6, (byte) 0x5d,
+            (byte) 0x02, (byte) 0xad, (byte) 0xd4, (byte) 0x2f, (byte) 0x4f, (byte) 0xab,
+            (byte) 0xb7, (byte) 0x9e, (byte) 0xc0, (byte) 0xf0, (byte) 0x3d, (byte) 0x66,
+            (byte) 0x0e, (byte) 0x20, (byte) 0x82, (byte) 0x7f, (byte) 0x22, (byte) 0x8f,
+            (byte) 0x81, (byte) 0xba, (byte) 0x47, (byte) 0xc7, (byte) 0xaf, (byte) 0xb6,
+            (byte) 0x0e, (byte) 0x78, (byte) 0xe3, (byte) 0x30, (byte) 0xd7, (byte) 0x6c,
+            (byte) 0x81, (byte) 0xc2, (byte) 0x05, (byte) 0x7e, (byte) 0xe9, (byte) 0xac,
+            (byte) 0x8d, (byte) 0x45, (byte) 0x25, (byte) 0xe8, (byte) 0x26, (byte) 0x39,
+            (byte) 0x88, (byte) 0x64, (byte) 0x2e, (byte) 0xc6, (byte) 0xed, (byte) 0xd4,
+            (byte) 0xad, (byte) 0x94, (byte) 0xc8, (byte) 0x4e, (byte) 0x4a, (byte) 0x71,
+            (byte) 0x1e, (byte) 0x11, (byte) 0x14, (byte) 0x03, (byte) 0x56, (byte) 0x02,
+            (byte) 0x28, (byte) 0x32, (byte) 0x8f, (byte) 0xe2, (byte) 0x16, (byte) 0x4a,
+            (byte) 0x62, (byte) 0xa6, (byte) 0x9a, (byte) 0x8d, (byte) 0xf8, (byte) 0x33,
+            (byte) 0x35, (byte) 0xa2, (byte) 0xc7, (byte) 0x70, (byte) 0xcc, (byte) 0x26,
+            (byte) 0x1e, (byte) 0x4d, (byte) 0x9c, (byte) 0x4e, (byte) 0x2b, (byte) 0xe8,
+            (byte) 0xfd, (byte) 0x07, (byte) 0x33, (byte) 0x15, (byte) 0x53, (byte) 0x11,
+            (byte) 0x5c, (byte) 0x6f, (byte) 0x5d, (byte) 0x23, (byte) 0x7b, (byte) 0x3f,
+            (byte) 0x73, (byte) 0xff, (byte) 0xf4, (byte) 0xbe, (byte) 0x1f, (byte) 0xe6,
+            (byte) 0x5a, (byte) 0xb8, (byte) 0x2b, (byte) 0xd2, (byte) 0xbe, (byte) 0xa0,
+            (byte) 0x91, (byte) 0x5d, (byte) 0xca, (byte) 0x89, (byte) 0xb3, (byte) 0xce,
+            (byte) 0x0a, (byte) 0x2b, (byte) 0xce, (byte) 0xb9, (byte) 0xbe, (byte) 0x5d,
+            (byte) 0xb2, (byte) 0xc2, (byte) 0xd6, (byte) 0xa9, (byte) 0xbc, (byte) 0x37,
+            (byte) 0xed, (byte) 0x9a, (byte) 0xba, (byte) 0x35, (byte) 0xf8, (byte) 0x6e,
+            (byte) 0x63, (byte) 0x76, (byte) 0xd1, (byte) 0x12, (byte) 0xf5, (byte) 0x89,
+            (byte) 0xf0, (byte) 0x13, (byte) 0x86, (byte) 0xe7, (byte) 0x1b, (byte) 0x94,
+            (byte) 0xcb, (byte) 0xc8, (byte) 0x5c, (byte) 0x4c, (byte) 0x1b, (byte) 0x8a,
+            (byte) 0x2d, (byte) 0x6b, (byte) 0x24, (byte) 0x1a, (byte) 0x38, (byte) 0x14,
+            (byte) 0x77, (byte) 0x49, (byte) 0xe5, (byte) 0x08, (byte) 0x25, (byte) 0xe4,
+            (byte) 0xa6, (byte) 0xcf, (byte) 0x62, (byte) 0xfd, (byte) 0x66, (byte) 0x28,
+            (byte) 0xf0, (byte) 0x3a, (byte) 0x9c, (byte) 0x31, (byte) 0xef, (byte) 0x48,
+            (byte) 0x2a, (byte) 0xd3, (byte) 0x3e, (byte) 0x29, (byte) 0xfa, (byte) 0x18,
+            (byte) 0x8f, (byte) 0xd6, (byte) 0xaa, (byte) 0x1d, (byte) 0x10, (byte) 0xcd,
+            (byte) 0x35, (byte) 0x25, (byte) 0x92, (byte) 0x48, (byte) 0xa0, (byte) 0x2c,
+            (byte) 0xc1, (byte) 0x31, (byte) 0xeb, (byte) 0x47, (byte) 0x5b, (byte) 0x22,
+            (byte) 0x52, (byte) 0x7c, (byte) 0xf5, (byte) 0xec, (byte) 0x76, (byte) 0x90,
+            (byte) 0x94, (byte) 0x58, (byte) 0xd9, (byte) 0xd6, (byte) 0xe0, (byte) 0x0a,
+            (byte) 0x3f, (byte) 0x09, (byte) 0x98, (byte) 0x03, (byte) 0xc5, (byte) 0x07,
+            (byte) 0x8f, (byte) 0x89, (byte) 0x1e, (byte) 0x62, (byte) 0x2c, (byte) 0xea,
+            (byte) 0x17, (byte) 0x0a, (byte) 0x2e, (byte) 0x68
+    };
+
     public void testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success() throws Exception {
         for (String provider : RSA_PROVIDERS) {
             testRSA_ECB_NoPadding_Private_OnlyDoFinal_Success(provider);
@@ -3552,21 +3681,38 @@
         addRsaOaepTest("SHA-256", MGF1ParameterSpec.SHA256, RSA_Vector2_OAEP_SHA256_MGF1_SHA256);
         addRsaOaepTest("SHA-384", MGF1ParameterSpec.SHA384, RSA_Vector2_OAEP_SHA384_MGF1_SHA384);
         addRsaOaepTest("SHA-512", MGF1ParameterSpec.SHA512, RSA_Vector2_OAEP_SHA512_MGF1_SHA512);
+        addRsaOaepTest("SHA-256", MGF1ParameterSpec.SHA1, RSA_Vector2_OAEP_SHA256_MGF1_SHA1_LABEL,
+                new byte[] { 0x01, 0x02, 0x03, (byte) 0xFF, (byte) 0xA0, 0x0A });
+        addRsaOaepTest("SHA-512", MGF1ParameterSpec.SHA512, RSA_Vector2_OAEP_SHA512_MGF1_SHA512_LABEL,
+                new byte[] { 0x01, 0x02, 0x03, (byte) 0xFF, (byte) 0xA0, 0x0A });
     }
 
     private static void addRsaOaepTest(String digest, MGF1ParameterSpec mgf1Spec, byte[] vector) {
+        addRsaOaepTest(digest, mgf1Spec, vector, null);
+    }
+
+    private static void addRsaOaepTest(String digest, MGF1ParameterSpec mgf1Spec, byte[] vector, byte[] label) {
+        final PSource pSource;
+        if (label == null) {
+            pSource = PSource.PSpecified.DEFAULT;
+        } else {
+            pSource = new PSource.PSpecified(label);
+        }
+
         if (mgf1Spec.getDigestAlgorithm().equals(digest)) {
-            RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
-                    "RSA/ECB/OAEPWith" + digest + "AndMGF1Padding",
-                    null,
-                    (PublicKey) getEncryptKey("RSA"),
-                    (PrivateKey) getDecryptKey("RSA"),
-                    RSA_Vector2_Plaintext,
-                    vector));
+            if (label == null) {
+                RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
+                        "RSA/ECB/OAEPWith" + digest + "AndMGF1Padding",
+                        null,
+                        (PublicKey) getEncryptKey("RSA"),
+                        (PrivateKey) getDecryptKey("RSA"),
+                        RSA_Vector2_Plaintext,
+                        vector));
+            }
 
             RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
                     "RSA/ECB/OAEPWith" + digest + "AndMGF1Padding",
-                    new OAEPParameterSpec(digest, "MGF1", mgf1Spec, PSource.PSpecified.DEFAULT),
+                    new OAEPParameterSpec(digest, "MGF1", mgf1Spec, pSource),
                     (PublicKey) getEncryptKey("RSA"),
                     (PrivateKey) getDecryptKey("RSA"),
                     RSA_Vector2_Plaintext,
@@ -3575,7 +3721,7 @@
 
         RSA_OAEP_CIPHER_TEST_PARAMS.add(new OAEPCipherTestParam(
                 "RSA/ECB/OAEPPadding",
-                new OAEPParameterSpec(digest, "MGF1", mgf1Spec, PSource.PSpecified.DEFAULT),
+                new OAEPParameterSpec(digest, "MGF1", mgf1Spec, pSource),
                 (PublicKey) getEncryptKey("RSA"),
                 (PrivateKey) getDecryptKey("RSA"),
                 RSA_Vector2_Plaintext,
@@ -3679,6 +3825,14 @@
                 MGF1ParameterSpec mgf1Spec = (MGF1ParameterSpec) oaepSpec.getMGFParameters();
                 logStream.append(", mgf1Hash=" + mgf1Spec.getDigestAlgorithm());
             }
+            logStream.append(", pSource=");
+            PSource pSource = oaepSpec.getPSource();
+            logStream.append(pSource.getAlgorithm());
+            if (pSource.getAlgorithm().equals("PSpecified")) {
+                logStream.append(":{");
+                logStream.append(Arrays.toString(((PSource.PSpecified) pSource).getValue()));
+                logStream.append('}');
+            }
             logStream.append('}');
         }
 
@@ -3691,6 +3845,17 @@
 
         c.init(Cipher.ENCRYPT_MODE, p.encryptKey, p.spec);
 
+        // This doesn't quite work on OAEPPadding unless it's the default case,
+        // because its size depends on the message digest algorithms used.
+        if (!p.transformation.endsWith("OAEPPADDING")) {
+            assertEquals(p.transformation + " getBlockSize() ENCRYPT_MODE",
+                    getExpectedBlockSize(p.transformation, Cipher.ENCRYPT_MODE, provider),
+                    c.getBlockSize());
+        }
+        assertTrue(p.transformation + " getOutputSize(0) ENCRYPT_MODE",
+                getExpectedOutputSize(p.transformation, Cipher.ENCRYPT_MODE, provider) <= c
+                        .getOutputSize(0));
+
         if (p.aad != null) {
             c.updateAAD(p.aad);
         }
@@ -3707,6 +3872,18 @@
 
         c.init(Cipher.DECRYPT_MODE, p.decryptKey, p.spec);
 
+        assertEquals(p.transformation + " getBlockSize() DECRYPT_MODE",
+                getExpectedBlockSize(p.transformation, Cipher.DECRYPT_MODE, provider),
+                c.getBlockSize());
+
+        // This doesn't quite work on OAEPPadding unless it's the default case,
+        // because its size depends on the message digest algorithms used.
+        if (!p.transformation.endsWith("OAEPPADDING")) {
+            assertTrue(p.transformation + " getOutputSize(0) DECRYPT_MODE",
+                    getExpectedOutputSize(p.transformation, Cipher.DECRYPT_MODE, provider) <= c
+                            .getOutputSize(0));
+        }
+
         if (!isAEAD(p.transformation)) {
             try {
                 c.updateAAD(new byte[8]);
@@ -3723,14 +3900,14 @@
                 throw maybe;
             }
         } catch (BadPaddingException maybe) {
-            // BC's OAEP has a bug where it doesn't support empty decrypt
+            // BC's OAEP has a bug where it doesn't support decrypt of a zero-length plaintext
             if (!("BC".equals(provider) && p.transformation.contains("OAEP"))) {
                 throw maybe;
             }
         }
 
-        // empty decrypt
-        {
+        // decrypt an empty ciphertext; not valid for RSA
+        if (!p.transformation.contains("OAEP")) {
             if ((!isAEAD(p.transformation)
                     && (StandardNames.IS_RI || provider.equals("AndroidOpenSSL") ||
                             (provider.equals("BC") && p.transformation.contains("/CTR/"))))
@@ -3753,11 +3930,6 @@
                     if (!isAEAD(p.transformation)) {
                         throw maybe;
                     }
-                } catch (BadPaddingException maybe) {
-                    // BC's OAEP has a bug where it doesn't support empty decrypt
-                    if (!("BC".equals(provider) && p.transformation.contains("OAEP"))) {
-                        throw maybe;
-                    }
                 }
                 try {
                     c.update(new byte[0]);
@@ -3771,11 +3943,6 @@
                     if (!isAEAD(p.transformation)) {
                         throw maybe;
                     }
-                } catch (BadPaddingException maybe) {
-                    // BC's OAEP has a bug where it doesn't support empty decrypt
-                    if (!("BC".equals(provider) && p.transformation.contains("OAEP"))) {
-                        throw maybe;
-                    }
                 }
             } else {
                 throw new AssertionError("Define your behavior here for " + provider);
diff --git a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
index 9281b43..809c290 100644
--- a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
@@ -37,6 +37,7 @@
     public void testKeyAgreement_getInstance_SuppliedProviderNotRegistered_Success()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
             }
@@ -52,6 +53,7 @@
     public void testKeyAgreement_getInstance_DoesNotSupportKeyClass_Success()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
                 put("KeyAgreement.FOO SupportedKeyClasses", "none");
@@ -76,6 +78,7 @@
     public void testKeyAgreement_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
                 put("KeyAgreement.FOO SupportedKeyClasses", "none");
diff --git a/luni/src/test/java/libcore/javax/crypto/MacTest.java b/luni/src/test/java/libcore/javax/crypto/MacTest.java
index b308f02..61da2bb 100644
--- a/luni/src/test/java/libcore/javax/crypto/MacTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/MacTest.java
@@ -16,13 +16,17 @@
 
 package libcore.javax.crypto;
 
-import junit.framework.TestCase;
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 import java.security.InvalidKeyException;
 import java.security.Provider;
 import java.security.Security;
-
+import java.util.Arrays;
 import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import junit.framework.TestCase;
 
 public class MacTest extends TestCase {
     private static abstract class MockProvider extends Provider {
@@ -42,6 +46,7 @@
     public void testMac_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
+            @Override
             public void setup() {
                 put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
                 put("Mac.FOO SupportedKeyClasses", "none");
@@ -69,4 +74,61 @@
         assertEquals("HmacSHA224", androidOpenSSLProvider.get("Alg.Alias.Mac.1.2.840.113549.2.8"));
         assertEquals("HmacSHA256", androidOpenSSLProvider.get("Alg.Alias.Mac.1.2.840.113549.2.9"));
     }
+
+    // Known answers from the SunJCE provider using the code below. Run with
+    //     vogar --classpath sunjce_provider.jar
+    //
+    // secretKeyFactory = SecretKeyFactory.getInstance("PBEWithHmacSHA" + shaVariant + "AndAES_128",
+    //        new com.sun.crypto.provider.SunJCE());
+    // pbeKeySpec = new PBEKeySpec(password);
+    //
+    // secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
+    // mac = Mac.getInstance("PBEWITHHMACSHA" + shaVariant, new com.sun.crypto.provider.SunJCE());
+    //        mac.init(secretKey, new PBEParameterSpec(salt, iterationCount));
+    // byte[] sunResult = mac.doFinal(plaintext);
+    private final byte[][] SUN_JCA_KNOWN_ANSWERS_FOR_SHA_VARIANTS = {
+            { 44, -78, -97, -109, -125, 49, 68, 58, -9, -99, -27, -122, 58, 27, 7, 45, 87, -92,
+                    -74, 64 },
+            { 59, -13, 28, 53, 79, -79, -127, 117, 3, -23, -75, -127, -44, -47, -43, 28, 76, -114,
+                    -110, 26, 59, 70, -91, 19, -52, 36, -64, -54 },
+            { 88, 54, -105, -122, 14, 73, -40, -43, 52, -21, -33, -103, 32, 81, 115, 53, 111, 78,
+                    32, -108, 71, -74, -84, 125, 80, 13, -35, -36, 27, 56, 32, 104 },
+            { -83, 60, -92, 44, -58, 86, -121, 104, 114, -67, 14, 80, 84, -48, -14, 38, 14, -62,
+                    -96, 118, 53, -59, -33, -90, 85, -110, 105, -119, -81, 57, 43, -66, 99, 106, 35,
+                    -16, -115, 29, -56, -52, -39, 102, -1, -90, 110, -52, 48, -32},
+            { -22, -69, -77, 11, -14, -128, -121, 5, 48, 18, 107, -22, 64, -45, 18, 60, 24, -42,
+                    -67, 111, 110, -99, -19, 14, -21, -43, 26, 68, -40, 82, 123, 39, 115, 34, 6,
+                    -67, 27, -73, -63, -56, -39, 65, -75, -14, -5, -94, -8, 126, -44, -97, 95, 31,
+                    61, 123, -17, 14, 117, 71, -45, 53, -76, -91, 91, -121}
+    };
+
+    /**
+     * Test that BC has the same results as the SunJCA provider for
+     */
+    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,
+                17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 };
+        byte[] salt = "saltsalt".getBytes(UTF_8);
+        char[] password = "password".toCharArray();
+        int iterationCount = 100;
+        int[] shaVariants = { 1, 224, 256, 384, 512 };
+
+        for (int shaVariantIndex = 0; shaVariantIndex < shaVariants.length; shaVariantIndex++) {
+            int shaVariant = shaVariants[shaVariantIndex];
+            SecretKeyFactory secretKeyFactory =
+                    SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA" + shaVariant, "BC");
+            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.init(secretKey);
+            byte[] bcResult = mac.doFinal(plaintext);
+            assertEquals(
+                    Arrays.toString(SUN_JCA_KNOWN_ANSWERS_FOR_SHA_VARIANTS[shaVariantIndex]),
+                    Arrays.toString(bcResult));
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java b/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java
index 0edeba7..d3ff9d5 100644
--- a/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java
+++ b/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java
@@ -26,7 +26,6 @@
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.MacSpi;
-import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.NoSuchPaddingException;
 import javax.crypto.ShortBufferException;
 
diff --git a/luni/src/test/java/libcore/javax/crypto/SecretKeyFactoryTest.java b/luni/src/test/java/libcore/javax/crypto/SecretKeyFactoryTest.java
index ef5adc9..0878bac 100644
--- a/luni/src/test/java/libcore/javax/crypto/SecretKeyFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/SecretKeyFactoryTest.java
@@ -16,6 +16,8 @@
 
 package libcore.javax.crypto;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.KeySpec;
 import java.util.Arrays;
@@ -171,7 +173,7 @@
     public void test_PBKDF2_b8312059() throws Exception {
 
         char[] password = "\u0141\u0142".toCharArray();
-        byte[] salt = "salt".getBytes();
+        byte[] salt = "salt".getBytes(UTF_8);
         int iterations = 4096;
         int keyLength = 160;
         byte[] expected_utf8 = new byte[] {
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
index 77d81db..aed6ce8 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParameterGeneratorTestDH.java
@@ -25,6 +25,7 @@
         super("DH", new AlgorithmParameterKeyAgreementHelper("DH"));
     }
 
+    @Override
     public void testAlgorithmParameterGenerator() throws Exception {
         super.testAlgorithmParameterGenerator();
     }
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
index f8a5b5d..6e62c03 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/AlgorithmParametersTestDH.java
@@ -61,6 +61,7 @@
     }
 
     // Broken Test: Suffers from DH slowness, disabling for now
+    @Override
     public void testAlgorithmParameters() throws Exception {
         super.testAlgorithmParameters();
     }
diff --git a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
index 1ef4c8c..5a74d68 100644
--- a/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
+++ b/luni/src/test/java/libcore/javax/crypto/spec/KeyPairGeneratorTestDH.java
@@ -26,6 +26,7 @@
     }
 
     // Broken Test: Takes ages due to DH computations. Disabling for now.
+    @Override
     public void testKeyPairGenerator() throws Exception {
         super.testKeyPairGenerator();
     }
diff --git a/luni/src/test/java/libcore/javax/net/ServerSocketFactoryTest.java b/luni/src/test/java/libcore/javax/net/ServerSocketFactoryTest.java
index 77996dd..edb184c 100644
--- a/luni/src/test/java/libcore/javax/net/ServerSocketFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ServerSocketFactoryTest.java
@@ -102,14 +102,14 @@
             }
             fail("Failed to exhaust backlog after " + max + " connections!");
         } catch (IOException expected) {
+        } finally {
+            for (Socket socket : backlog) {
+                socket.close();
+            }
         }
 
         System.out.println("backlog peaked at " + peak);
 
-        for (Socket socket : backlog) {
-            socket.close();
-        }
-
         /*
          * In 4.5 of UNIX Network Programming, Stevens says:
          *     "Berkeley-derived implementations add a fudge factor to the
diff --git a/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java b/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
index b99a3f1..cd693c9 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/KeyManagerFactoryTest.java
@@ -26,7 +26,6 @@
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
-import java.util.Locale;
 import java.util.Set;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
@@ -42,6 +41,7 @@
 
     private TestKeyStore testKeyStore;
 
+    @Override
     protected void setUp() throws Exception {
         // note the rare usage of DSA keys here in addition to RSA
         testKeyStore = new TestKeyStore.Builder()
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
index 1628260..d9a7b4f 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -16,6 +16,8 @@
 
 package libcore.javax.net.ssl;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
@@ -124,7 +126,7 @@
                 new PSKKeyManagerProxy() {
             @Override
             protected SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
-                return new SecretKeySpec("Just an arbitrary key".getBytes(), "RAW");
+                return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
             }
         });
         TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
@@ -223,9 +225,9 @@
                         "TLS".equalsIgnoreCase(c.clientContext.getProtocol())
                                 && cipherSuite.contains("_CBC_");
 
-                assertSendsCorrectly("This is the client. Hello!".getBytes(),
+                assertSendsCorrectly("This is the client. Hello!".getBytes(UTF_8),
                         pair.client, pair.server, needsRecordSplit);
-                assertSendsCorrectly("This is the server. Hi!".getBytes(),
+                assertSendsCorrectly("This is the server. Hi!".getBytes(UTF_8),
                         pair.server, pair.client, needsRecordSplit);
             } finally {
                 if (pair != null) {
@@ -818,11 +820,12 @@
             final CountDownLatch startUpSync = new CountDownLatch(2);
             ExecutorService executor = Executors.newFixedThreadPool(2);
             Future<Void> client = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     startUpSync.countDown();
 
                     for (int i = 0; i < NUM_STRESS_ITERATIONS; i++) {
-                        assertSendsCorrectly("This is the client. Hello!".getBytes(),
+                        assertSendsCorrectly("This is the client. Hello!".getBytes(UTF_8),
                                 pair.client, pair.server, false);
                     }
 
@@ -830,11 +833,12 @@
                 }
             });
             Future<Void> server = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     startUpSync.countDown();
 
                     for (int i = 0; i < NUM_STRESS_ITERATIONS; i++) {
-                        assertSendsCorrectly("This is the server. Hi!".getBytes(),
+                        assertSendsCorrectly("This is the server. Hi!".getBytes(UTF_8),
                                 pair.server, pair.client, false);
                     }
 
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index d2ad9fd..4f12841b 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -16,6 +16,8 @@
 
 package libcore.javax.net.ssl;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.EOFException;
@@ -125,14 +127,14 @@
 
         String clientToServerString = "this is sent from the client to the server...";
         String serverToClientString = "... and this from the server to the client";
-        byte[] clientToServer = clientToServerString.getBytes();
-        byte[] serverToClient = serverToClientString.getBytes();
+        byte[] clientToServer = clientToServerString.getBytes(UTF_8);
+        byte[] serverToClient = serverToClientString.getBytes(UTF_8);
 
         KeyManager pskKeyManager = PSKKeyManagerProxy.getConscryptPSKKeyManager(
                 new PSKKeyManagerProxy() {
             @Override
             protected SecretKey getKey(String identityHint, String identity, Socket socket) {
-                return new SecretKeySpec("Just an arbitrary key".getBytes(), "RAW");
+                return new SecretKeySpec("Just an arbitrary key".getBytes(UTF_8), "RAW");
             }
         });
         TestSSLContext c = TestSSLContext.createWithAdditionalKeyManagers(
@@ -533,6 +535,7 @@
         executor.shutdown();
         final boolean[] handshakeCompletedListenerCalled = new boolean[1];
         client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
+            @Override
             public void handshakeCompleted(HandshakeCompletedEvent event) {
                 try {
                     SSLSession session = event.getSession();
@@ -655,6 +658,7 @@
         });
         executor.shutdown();
         client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
+            @Override
             public void handshakeCompleted(HandshakeCompletedEvent event) {
                 throw expectedException;
             }
@@ -1108,6 +1112,7 @@
 
         // ...so are a lot of other operations...
         HandshakeCompletedListener l = new HandshakeCompletedListener () {
+            @Override
             public void handshakeCompleted(HandshakeCompletedEvent e) {}
         };
         client.addHandshakeCompletedListener(l);
@@ -1385,10 +1390,10 @@
 
         // Reflection is used so this can compile on the RI
         String expectedClassName = "com.android.org.conscrypt.OpenSSLSocketImpl";
-        Class actualClass = client.getClass();
+        Class<?> actualClass = client.getClass();
         assertEquals(expectedClassName, actualClass.getName());
         Method setSoWriteTimeout = actualClass.getMethod("setSoWriteTimeout",
-                                                         new Class[] { Integer.TYPE });
+                                                         new Class<?>[] { Integer.TYPE });
         setSoWriteTimeout.invoke(client, 1);
 
 
@@ -1953,6 +1958,7 @@
 
         ExecutorService executor = Executors.newFixedThreadPool(2);
         Future<Void> s = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     server.setEnabledProtocols(new String[] { "TLSv1.2" });
                     server.setEnabledCipherSuites(serverCipherSuites);
@@ -1961,6 +1967,7 @@
                 }
             });
         Future<Void> c = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     client.setEnabledProtocols(new String[] { "TLSv1.2" });
                     client.setEnabledCipherSuites(clientCipherSuites);
@@ -1991,6 +1998,7 @@
 
         ExecutorService executor = Executors.newFixedThreadPool(2);
         Future<Void> s = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     server.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1.1" });
                     server.startHandshake();
@@ -1998,6 +2006,7 @@
                 }
             });
         Future<Void> c = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     client.setEnabledProtocols(new String[] { "TLSv1.1" });
                     client.startHandshake();
@@ -2034,6 +2043,7 @@
 
         ExecutorService executor = Executors.newFixedThreadPool(2);
         Future<Void> s = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     server.setEnabledProtocols(new String[] { "TLSv1.1", "TLSv1" });
                     server.setEnabledCipherSuites(serverCipherSuites);
@@ -2049,6 +2059,7 @@
                 }
             });
         Future<Void> c = executor.submit(new Callable<Void>() {
+                @Override
                 public Void call() throws Exception {
                     client.setEnabledProtocols(new String[] { "TLSv1" });
                     client.setEnabledCipherSuites(clientCipherSuites);
@@ -2083,6 +2094,7 @@
 
         ExecutorService executor = Executors.newFixedThreadPool(2);
         Future<Void> c = executor.submit(new Callable<Void>() {
+            @Override
             public Void call() throws Exception {
                 try {
                     client.startHandshake();
@@ -2095,6 +2107,7 @@
             }
         });
         Future<Void> s = executor.submit(new Callable<Void>() {
+            @Override
             public Void call() throws Exception {
                 // Wait until the client sends something.
                 byte[] scratch = new byte[8192];
@@ -2134,6 +2147,7 @@
 
         ExecutorService executor = Executors.newFixedThreadPool(2);
         Future<Void> s = executor.submit(new Callable<Void>() {
+            @Override
             public Void call() throws Exception {
                 try {
                     server.startHandshake();
@@ -2146,6 +2160,7 @@
             }
         });
         Future<Void> c = executor.submit(new Callable<Void>() {
+            @Override
             public Void call() throws Exception {
                 // Send bogus ClientHello:
                 // TLSv1.2 Record Layer: Handshake Protocol: Client Hello
@@ -2225,11 +2240,9 @@
         final SSLSocket client = (SSLSocket)
             context.clientContext.getSocketFactory().createSocket();
 
-        try {
-            client.setEnabledProtocols(new String[] {"SSLv3"});
-            fail("SSLSocket should not support SSLv3 protocol");
-        } catch (IllegalArgumentException expected) {
-        }
+        // For app compatibility, SSLv3 is stripped out when setting only.
+        client.setEnabledProtocols(new String[] {"SSLv3"});
+        assertEquals(0, client.getEnabledProtocols().length);
 
         try {
             client.setEnabledProtocols(new String[] {"SSL"});
diff --git a/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java b/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
index fc312fc..da85c7d 100644
--- a/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
+++ b/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
@@ -28,8 +28,9 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.logging.ErrorManager;
@@ -214,6 +215,7 @@
             logger.publish(record);
             assertNull(mockErrorManager.getMostRecentException());
             server.assertDataTransmittedByClient();
+            logger.close();
         }
 
         // Assert that client does not transmit any data when cleartext traffic is not permitted.
@@ -235,8 +237,8 @@
     private static class CapturingServerSocket implements Closeable {
         private final ServerSocket mSocket;
         private final int mPort;
-        private final Thread mListeningThread;
-        private final FutureTask<byte[]> mFirstChunkReceivedFuture;
+        private final ExecutorService executor;
+        private final Future<byte[]> mFirstChunkReceivedFuture;
 
         /**
          * Constructs a new socket listening on a local port.
@@ -252,32 +254,29 @@
         public CapturingServerSocket(final byte[] replyOnConnect) throws IOException {
             mSocket = new ServerSocket(0);
             mPort = mSocket.getLocalPort();
-            mFirstChunkReceivedFuture = new FutureTask<byte[]>(new Callable<byte[]>() {
-                @Override
-                public byte[] call() throws Exception {
-                    try (Socket client = mSocket.accept()) {
-                        // Reply (if requested)
-                        if (replyOnConnect != null) {
-                            client.getOutputStream().write(replyOnConnect);
-                            client.getOutputStream().flush();
-                        }
-
-                        // Read request
-                        byte[] buf = new byte[64 * 1024];
-                        int chunkSize = client.getInputStream().read(buf);
-                        if (chunkSize == -1) {
-                            // Connection closed without any data received
-                            return new byte[0];
-                        }
-                        // Received some data
-                        return Arrays.copyOf(buf, chunkSize);
-                    } finally {
-                        IoUtils.closeQuietly(mSocket);
+            Callable<byte[]> callable = () -> {
+                try (Socket client = mSocket.accept()) {
+                    // Reply (if requested)
+                    if (replyOnConnect != null) {
+                        client.getOutputStream().write(replyOnConnect);
+                        client.getOutputStream().flush();
                     }
+
+                    // Read request
+                    byte[] buf = new byte[64 * 1024];
+                    int chunkSize = client.getInputStream().read(buf);
+                    if (chunkSize == -1) {
+                        // Connection closed without any data received
+                        return new byte[0];
+                    }
+                    // Received some data
+                    return Arrays.copyOf(buf, chunkSize);
+                } finally {
+                    IoUtils.closeQuietly(mSocket);
                 }
-            });
-            mListeningThread = new Thread(mFirstChunkReceivedFuture);
-            mListeningThread.start();
+            };
+            executor = Executors.newSingleThreadExecutor();
+            mFirstChunkReceivedFuture = executor.submit(callable);
         }
 
         public int getPort() {
@@ -291,12 +290,12 @@
         @Override
         public void close() {
             IoUtils.closeQuietly(mSocket);
-            mListeningThread.interrupt();
+            executor.shutdown();
         }
 
         private void assertDataTransmittedByClient()
                 throws Exception {
-            byte[] firstChunkFromClient = getFirstReceivedChunkFuture().get(2, TimeUnit.SECONDS);
+            byte[] firstChunkFromClient = getFirstReceivedChunkFuture().get(4, TimeUnit.SECONDS);
             if ((firstChunkFromClient == null) || (firstChunkFromClient.length == 0)) {
                 fail("Client did not transmit any data to server");
             }
@@ -306,7 +305,7 @@
                 throws Exception {
             byte[] firstChunkFromClient;
             try {
-                firstChunkFromClient = getFirstReceivedChunkFuture().get(2, TimeUnit.SECONDS);
+                firstChunkFromClient = getFirstReceivedChunkFuture().get(4, TimeUnit.SECONDS);
             } catch (TimeoutException expected) {
                 return;
             }
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
index e240f6f..1a2ac23 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
@@ -22,6 +22,7 @@
 
 package org.apache.harmony.crypto.tests.javax.crypto;
 
+import java.nio.DirectByteBuffer;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
@@ -35,6 +36,7 @@
 import javax.crypto.ShortBufferException;
 import javax.crypto.CipherSpi;
 import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import junit.framework.TestCase;
 
@@ -298,6 +300,137 @@
         bb2.position(0);
         assertTrue("Incorrect result", cSpi.engineDoFinal(bb1, bb2) > 0);
     }
+
+    public void testCrypt_doNotCallPositionInNonArrayBackedInputBuffer() throws Exception {
+        ByteBuffer nonArrayBackedInputBuffer = new MockNonArrayBackedByteBuffer(10, false);
+        ByteBuffer nonArrayBackedOutputBuffer = new MockNonArrayBackedByteBuffer(10, false);
+        Mock_CipherSpi cipherSpi = new Mock_CipherSpi() {
+            public int engineGetOutputSize(int inputLength) {
+                return inputLength;
+            }
+        };
+        cipherSpi.engineUpdate(nonArrayBackedInputBuffer, nonArrayBackedOutputBuffer);
+        assertEquals(0, nonArrayBackedInputBuffer.position());
+    }
+
+    public void testCrypt_doNotCallPutForZeroLengthOutput() throws Exception {
+        ByteBuffer nonArrayBackedInputBuffer = new MockNonArrayBackedByteBuffer(10, false);
+        ByteBuffer nonArrayBackedOutputBuffer = new MockNonArrayBackedByteBuffer(10, false) {
+            @Override
+            public ByteBuffer put(byte[] dst, int offset, int length) {
+                if (length == 0) {
+                    throw new IllegalStateException("put shouldn't be called with length 0");
+                }
+                return this;
+            }
+        };
+
+        Mock_CipherSpi cipherSpi = new Mock_CipherSpi() {
+            public int engineUpdate(
+                    byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
+                return 0;
+            }
+        };
+
+        // The put method is not called in the output buffer and so the test passes.
+        cipherSpi.engineUpdate(nonArrayBackedInputBuffer, nonArrayBackedOutputBuffer);
+    }
+
+    // In case a call to engineGetOutputSize returns 0 for the whole input size, but a positive
+    // value for the chunk size to be written, check that the positive output size is used in the
+    // second attempt to read from the the buffer.
+    public void testCrypt_outputSizeUpdatedAfterShortBufferException()
+            throws Exception {
+
+        // 4096 is the value hardcoded for a maximum array allocation in CipherSpi#getTempArraySize
+        final int maxInternalArrayAllocation = 4096;
+        // The length of the input is greater than the max chunk allowed, so the size of the chunk
+        // and the size of the input will differ.
+        final int testInputLength = maxInternalArrayAllocation + 1;
+        // Length to be returned the second time engineGetOutputSize is called (that is, when it's
+        // called with maxInternalArrayAllocation). First length returned (that is, when it's
+        // called with testInputLength) is 0.
+        final int testSecondOutputLength = 1000;
+
+        final AtomicInteger firstGetLength = new AtomicInteger(0);
+        final AtomicInteger secondGetLength = new AtomicInteger(0);
+
+        ByteBuffer inputBuffer = new MockNonArrayBackedByteBuffer(testInputLength, false) {
+            private boolean getWasCalled = false;
+
+            @Override
+            public ByteBuffer get(byte[] dst, int offset, int length) {
+                if (!getWasCalled) {
+                    getWasCalled = true;
+                    firstGetLength.set(length);
+                } else {
+                    if (secondGetLength.get() == 0) {
+                        secondGetLength.set(length);
+                    }
+                }
+                return this;
+            }
+        };
+
+        ByteBuffer outputBuffer = new MockNonArrayBackedByteBuffer(10, false);
+
+        Mock_CipherSpi cipherSpi = new Mock_CipherSpi() {
+            @Override
+            public int engineGetOutputSize(int inputLength) {
+                if (inputLength == testInputLength) {
+                    return 0;
+                } else if (inputLength == maxInternalArrayAllocation) {
+                    return testSecondOutputLength;
+                } else {
+                    throw new IllegalStateException("Unexpected value " + inputLength);
+                }
+            }
+
+            @Override
+            public int engineUpdate(
+                    byte[] inArray, int inOfs, int inLen, byte[] outArray, int outputOffset)
+                    throws ShortBufferException {
+                if (inLen == maxInternalArrayAllocation) {
+                    throw new ShortBufferException("to be caught in order to retry with a new"
+                            + "output size");
+                }
+                return 0;
+            }
+        };
+
+        cipherSpi.engineUpdate(inputBuffer, outputBuffer);
+
+        assertEquals(
+                "first call to get must use the input length, as the output length "
+                        + "from engineGetOutputSize is 0",
+                maxInternalArrayAllocation,
+                firstGetLength.get());
+
+        assertEquals(
+                "second call to get must use the new output length",
+                testSecondOutputLength,
+                secondGetLength.get());
+    }
+
+    // The tests using ByteBuffer depend on final methods (like hasArray) that cannot be mocked in
+    // Mockito, so the mock is done manually. ByteBuffer has abstract methods that are
+    // package-private, so extending DirectByteBuffer. It happens to be not backed by an array, so
+    // we use it when we need a byte buffer not array-backed.
+    private class MockNonArrayBackedByteBuffer extends DirectByteBuffer {
+        public MockNonArrayBackedByteBuffer(int capacity, boolean isReadOnly) {
+            super(capacity, 0 /* addr */, null /* fd */, null /* unmapper */, isReadOnly);
+        }
+
+        @Override
+        public ByteBuffer get(byte[] dst, int offset, int length) {
+            return this;
+        }
+
+        @Override
+        public ByteBuffer put(byte[] dst, int offset, int length) {
+            return this;
+        }
+    }
 }
 /**
  *
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
index 61c6d03..9c562ee 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
@@ -531,7 +531,7 @@
         try {
             uc2.getInputStream();
             fail();
-        } catch (Throwable expected) {
+        } catch (IOException expected) {
         }
     }
 
diff --git a/ojluni/src/main/java/java/io/InputStream.java b/ojluni/src/main/java/java/io/InputStream.java
index 63d31d5..6c46a40 100644
--- a/ojluni/src/main/java/java/io/InputStream.java
+++ b/ojluni/src/main/java/java/io/InputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -193,8 +193,10 @@
      * up skipping over some smaller number of bytes, possibly <code>0</code>.
      * This may result from any of a number of conditions; reaching end of file
      * before <code>n</code> bytes have been skipped is only one possibility.
-     * The actual number of bytes skipped is returned.  If <code>n</code> is
-     * negative, no bytes are skipped.
+     * The actual number of bytes skipped is returned. If {@code n} is
+     * negative, the {@code skip} method for class {@code InputStream} always
+     * returns 0, and no bytes are skipped. Subclasses may handle the negative
+     * value differently.
      *
      * <p> The <code>skip</code> method of this class creates a
      * byte array and then repeatedly reads into it until <code>n</code> bytes
@@ -304,8 +306,7 @@
      *
      * <p> The general contract of <code>reset</code> is:
      *
-     * <p><ul>
-     *
+     * <ul>
      * <li> If the method <code>markSupported</code> returns
      * <code>true</code>, then:
      *
diff --git a/ojluni/src/main/java/java/io/InputStreamReader.java b/ojluni/src/main/java/java/io/InputStreamReader.java
index 2cda0ce..e131dca 100644
--- a/ojluni/src/main/java/java/io/InputStreamReader.java
+++ b/ojluni/src/main/java/java/io/InputStreamReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 /**
  * An InputStreamReader is a bridge from byte streams to character streams: It
  * reads bytes and decodes them into characters using a specified {@link
- * java.nio.charset.Charset <code>charset</code>}.  The charset that it uses
+ * java.nio.charset.Charset charset}.  The charset that it uses
  * may be specified by name or may be given explicitly, or the platform's
  * default charset may be accepted.
  *
@@ -86,7 +86,7 @@
      *
      * @param  charsetName
      *         The name of a supported
-     *         {@link java.nio.charset.Charset </code>charset<code>}
+     *         {@link java.nio.charset.Charset charset}
      *
      * @exception  UnsupportedEncodingException
      *             If the named charset is not supported
@@ -101,7 +101,7 @@
     }
 
     /**
-     * Creates an InputStreamReader that uses the given charset. </p>
+     * Creates an InputStreamReader that uses the given charset.
      *
      * @param  in       An InputStream
      * @param  cs       A charset
@@ -117,7 +117,7 @@
     }
 
     /**
-     * Creates an InputStreamReader that uses the given charset decoder.  </p>
+     * Creates an InputStreamReader that uses the given charset decoder.
      *
      * @param  in       An InputStream
      * @param  dec      A charset decoder
diff --git a/ojluni/src/main/java/java/io/LineNumberInputStream.java b/ojluni/src/main/java/java/io/LineNumberInputStream.java
index d3b5d9b..1f37a98 100644
--- a/ojluni/src/main/java/java/io/LineNumberInputStream.java
+++ b/ojluni/src/main/java/java/io/LineNumberInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,13 +30,13 @@
  * functionality of keeping track of the current line number.
  * <p>
  * A line is a sequence of bytes ending with a carriage return
- * character (<code>'&#92;r'</code>), a newline character
- * (<code>'&#92;n'</code>), or a carriage return character followed
+ * character ({@code '\u005Cr'}), a newline character
+ * ({@code '\u005Cn'}), or a carriage return character followed
  * immediately by a linefeed character. In all three cases, the line
  * terminating character(s) are returned as a single newline character.
  * <p>
- * The line number begins at <code>0</code>, and is incremented by
- * <code>1</code> when a <code>read</code> returns a newline character.
+ * The line number begins at {@code 0}, and is incremented by
+ * {@code 1} when a {@code read} returns a newline character.
  *
  * @author     Arthur van Hoff
  * @see        java.io.LineNumberReader
@@ -66,27 +66,28 @@
 
     /**
      * Reads the next byte of data from this input stream. The value
-     * byte is returned as an <code>int</code> in the range
-     * <code>0</code> to <code>255</code>. If no byte is available
+     * byte is returned as an {@code int} in the range
+     * {@code 0} to {@code 255}. If no byte is available
      * because the end of the stream has been reached, the value
-     * <code>-1</code> is returned. This method blocks until input data
+     * {@code -1} is returned. This method blocks until input data
      * is available, the end of the stream is detected, or an exception
      * is thrown.
      * <p>
-     * The <code>read</code> method of
-     * <code>LineNumberInputStream</code> calls the <code>read</code>
+     * The {@code read} method of
+     * {@code LineNumberInputStream} calls the {@code read}
      * method of the underlying input stream. It checks for carriage
      * returns and newline characters in the input, and modifies the
      * current line number as appropriate. A carriage-return character or
      * a carriage return followed by a newline character are both
      * converted into a single newline character.
      *
-     * @return     the next byte of data, or <code>-1</code> if the end of this
+     * @return     the next byte of data, or {@code -1} if the end of this
      *             stream is reached.
      * @exception  IOException  if an I/O error occurs.
      * @see        java.io.FilterInputStream#in
      * @see        java.io.LineNumberInputStream#getLineNumber()
      */
+    @SuppressWarnings("fallthrough")
     public int read() throws IOException {
         int c = pushBack;
 
@@ -110,18 +111,18 @@
     }
 
     /**
-     * Reads up to <code>len</code> bytes of data from this input stream
+     * Reads up to {@code len} bytes of data from this input stream
      * into an array of bytes. This method blocks until some input is available.
      * <p>
-     * The <code>read</code> method of
-     * <code>LineNumberInputStream</code> repeatedly calls the
-     * <code>read</code> method of zero arguments to fill in the byte array.
+     * The {@code read} method of
+     * {@code LineNumberInputStream} repeatedly calls the
+     * {@code read} method of zero arguments to fill in the byte array.
      *
      * @param      b     the buffer into which the data is read.
      * @param      off   the start offset of the data.
      * @param      len   the maximum number of bytes read.
      * @return     the total number of bytes read into the buffer, or
-     *             <code>-1</code> if there is no more data because the end of
+     *             {@code -1} if there is no more data because the end of
      *             this stream has been reached.
      * @exception  IOException  if an I/O error occurs.
      * @see        java.io.LineNumberInputStream#read()
@@ -159,15 +160,15 @@
     }
 
     /**
-     * Skips over and discards <code>n</code> bytes of data from this
-     * input stream. The <code>skip</code> method may, for a variety of
+     * Skips over and discards {@code n} bytes of data from this
+     * input stream. The {@code skip} method may, for a variety of
      * reasons, end up skipping over some smaller number of bytes,
-     * possibly <code>0</code>. The actual number of bytes skipped is
-     * returned.  If <code>n</code> is negative, no bytes are skipped.
+     * possibly {@code 0}. The actual number of bytes skipped is
+     * returned.  If {@code n} is negative, no bytes are skipped.
      * <p>
-     * The <code>skip</code> method of <code>LineNumberInputStream</code> creates
+     * The {@code skip} method of {@code LineNumberInputStream} creates
      * a byte array and then repeatedly reads into it until
-     * <code>n</code> bytes have been read or the end of the stream has
+     * {@code n} bytes have been read or the end of the stream has
      * been reached.
      *
      * @param      n   the number of bytes to be skipped.
@@ -224,12 +225,12 @@
      * <p>
      * Note that if the underlying input stream is able to supply
      * <i>k</i> input characters without blocking, the
-     * <code>LineNumberInputStream</code> can guarantee only to provide
+     * {@code LineNumberInputStream} can guarantee only to provide
      * <i>k</i>/2 characters without blocking, because the
      * <i>k</i> characters from the underlying input stream might
-     * consist of <i>k</i>/2 pairs of <code>'&#92;r'</code> and
-     * <code>'&#92;n'</code>, which are converted to just
-     * <i>k</i>/2 <code>'&#92;n'</code> characters.
+     * consist of <i>k</i>/2 pairs of {@code '\u005Cr'} and
+     * {@code '\u005Cn'}, which are converted to just
+     * <i>k</i>/2 {@code '\u005Cn'} characters.
      *
      * @return     the number of bytes that can be read from this input stream
      *             without blocking.
@@ -242,12 +243,12 @@
 
     /**
      * Marks the current position in this input stream. A subsequent
-     * call to the <code>reset</code> method repositions this stream at
+     * call to the {@code reset} method repositions this stream at
      * the last marked position so that subsequent reads re-read the same bytes.
      * <p>
-     * The <code>mark</code> method of
-     * <code>LineNumberInputStream</code> remembers the current line
-     * number in a private variable, and then calls the <code>mark</code>
+     * The {@code mark} method of
+     * {@code LineNumberInputStream} remembers the current line
+     * number in a private variable, and then calls the {@code mark}
      * method of the underlying input stream.
      *
      * @param   readlimit   the maximum limit of bytes that can be read before
@@ -263,12 +264,12 @@
 
     /**
      * Repositions this stream to the position at the time the
-     * <code>mark</code> method was last called on this input stream.
+     * {@code mark} method was last called on this input stream.
      * <p>
-     * The <code>reset</code> method of
-     * <code>LineNumberInputStream</code> resets the line number to be
-     * the line number at the time the <code>mark</code> method was
-     * called, and then calls the <code>reset</code> method of the
+     * The {@code reset} method of
+     * {@code LineNumberInputStream} resets the line number to be
+     * the line number at the time the {@code mark} method was
+     * called, and then calls the {@code reset} method of the
      * underlying input stream.
      * <p>
      * Stream marks are intended to be used in
diff --git a/ojluni/src/main/java/java/io/LineNumberReader.java b/ojluni/src/main/java/java/io/LineNumberReader.java
index 31f1e87..29884fd 100644
--- a/ojluni/src/main/java/java/io/LineNumberReader.java
+++ b/ojluni/src/main/java/java/io/LineNumberReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -120,6 +120,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      */
+    @SuppressWarnings("fallthrough")
     public int read() throws IOException {
         synchronized (lock) {
             int c = super.read();
@@ -159,6 +160,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      */
+    @SuppressWarnings("fallthrough")
     public int read(char cbuf[], int off, int len) throws IOException {
         synchronized (lock) {
             int n = super.read(cbuf, off, len);
diff --git a/ojluni/src/main/java/java/io/ObjectInputStream.java b/ojluni/src/main/java/java/io/ObjectInputStream.java
index 419d095..f562fe4 100644
--- a/ojluni/src/main/java/java/io/ObjectInputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectInputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -111,7 +111,7 @@
  *
  * <p>Serializable classes that require special handling during the
  * serialization and deserialization process should implement the following
- * methods:<p>
+ * methods:
  *
  * <pre>
  * private void writeObject(java.io.ObjectOutputStream stream)
@@ -316,6 +316,7 @@
      * @throws  SecurityException if a security manager exists and its
      *          <code>checkPermission</code> method denies enabling
      *          subclassing.
+     * @throws  IOException if an I/O error occurs while creating this stream
      * @see SecurityManager#checkPermission
      * @see java.io.SerializablePermission
      */
@@ -493,11 +494,12 @@
     public void defaultReadObject()
         throws IOException, ClassNotFoundException
     {
-        if (curContext == null) {
+        SerialCallbackContext ctx = curContext;
+        if (ctx == null) {
             throw new NotActiveException("not in call to readObject");
         }
-        Object curObj = curContext.getObj();
-        ObjectStreamClass curDesc = curContext.getDesc();
+        Object curObj = ctx.getObj();
+        ObjectStreamClass curDesc = ctx.getDesc();
         bin.setBlockDataMode(false);
         defaultReadFields(curObj, curDesc);
         bin.setBlockDataMode(true);
@@ -531,11 +533,12 @@
     public ObjectInputStream.GetField readFields()
         throws IOException, ClassNotFoundException
     {
-        if (curContext == null) {
+        SerialCallbackContext ctx = curContext;
+        if (ctx == null) {
             throw new NotActiveException("not in call to readObject");
         }
-        Object curObj = curContext.getObj();
-        ObjectStreamClass curDesc = curContext.getDesc();
+        Object curObj = ctx.getObj();
+        ObjectStreamClass curDesc = ctx.getDesc();
         bin.setBlockDataMode(false);
         GetFieldImpl getField = new GetFieldImpl(curDesc);
         getField.readFields();
@@ -693,9 +696,9 @@
         boolean hasNonPublicInterface = false;
 
         // define proxy in class loader of non-public interface(s), if any
-        Class[] classObjs = new Class[interfaces.length];
+        Class<?>[] classObjs = new Class<?>[interfaces.length];
         for (int i = 0; i < interfaces.length; i++) {
-            Class cl = Class.forName(interfaces[i], false, latestLoader);
+            Class<?> cl = Class.forName(interfaces[i], false, latestLoader);
             if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
                 if (hasNonPublicInterface) {
                     if (nonPublicLoader != cl.getClassLoader()) {
@@ -1233,7 +1236,7 @@
      * "enableSubclassImplementation" SerializablePermission is checked.
      */
     private void verifySubclass() {
-        Class cl = getClass();
+        Class<?> cl = getClass();
         if (cl == ObjectInputStream.class) {
             return;
         }
@@ -1477,12 +1480,12 @@
      * ClassNotFoundException will be associated with the class' handle in the
      * handle table).
      */
-    private Class readClass(boolean unshared) throws IOException {
+    private Class<?> readClass(boolean unshared) throws IOException {
         if (bin.readByte() != TC_CLASS) {
             throw new InternalError();
         }
         ObjectStreamClass desc = readClassDesc(false);
-        Class cl = desc.forClass();
+        Class<?> cl = desc.forClass();
         passHandle = handles.assign(unshared ? unsharedMarker : cl);
 
         ClassNotFoundException resolveEx = desc.getResolveException();
@@ -1552,7 +1555,7 @@
             ifaces[i] = bin.readUTF();
         }
 
-        Class cl = null;
+        Class<?> cl = null;
         ClassNotFoundException resolveEx = null;
         bin.setBlockDataMode(true);
         try {
@@ -1605,7 +1608,7 @@
                 "failed to read class descriptor").initCause(ex);
         }
 
-        Class cl = null;
+        Class<?> cl = null;
         ClassNotFoundException resolveEx = null;
         bin.setBlockDataMode(true);
         final boolean checksRequired = isCustomSubclass();
@@ -1665,7 +1668,7 @@
         int len = bin.readInt();
 
         Object array = null;
-        Class cl, ccl = null;
+        Class<?> cl, ccl = null;
         if ((cl = desc.forClass()) != null) {
             ccl = cl.getComponentType();
             array = Array.newInstance(ccl, len);
@@ -1718,7 +1721,7 @@
      * Reads in and returns enum constant, or null if enum type is
      * unresolvable.  Sets passHandle to enum constant's assigned handle.
      */
-    private Enum readEnum(boolean unshared) throws IOException {
+    private Enum<?> readEnum(boolean unshared) throws IOException {
         if (bin.readByte() != TC_ENUM) {
             throw new InternalError();
         }
@@ -1735,24 +1738,26 @@
         }
 
         String name = readString(false);
-        Enum en = null;
-        Class cl = desc.forClass();
+        Enum<?> result = null;
+        Class<?> cl = desc.forClass();
         if (cl != null) {
             try {
-                en = Enum.valueOf(cl, name);
+                @SuppressWarnings("unchecked")
+                Enum<?> en = Enum.valueOf((Class)cl, name);
+                result = en;
             } catch (IllegalArgumentException ex) {
                 throw (IOException) new InvalidObjectException(
                     "enum constant " + name + " does not exist in " +
                     cl).initCause(ex);
             }
             if (!unshared) {
-                handles.setObject(enumHandle, en);
+                handles.setObject(enumHandle, result);
             }
         }
 
         handles.finish(enumHandle);
         passHandle = enumHandle;
-        return en;
+        return result;
     }
 
     /**
@@ -1827,6 +1832,8 @@
         throws IOException
     {
         SerialCallbackContext oldContext = curContext;
+        if (oldContext != null)
+            oldContext.check();
         curContext = null;
         try {
             boolean blocked = desc.hasBlockExternalData();
@@ -1851,6 +1858,8 @@
                 skipCustomData();
             }
         } finally {
+            if (oldContext != null)
+                oldContext.check();
             curContext = oldContext;
         }
         /*
@@ -1881,12 +1890,12 @@
             ObjectStreamClass slotDesc = slots[i].desc;
 
             if (slots[i].hasData) {
-                if (obj != null &&
-                    slotDesc.hasReadObjectMethod() &&
-                    handles.lookupException(passHandle) == null)
-                {
+                if (obj == null || handles.lookupException(passHandle) != null) {
+                    defaultReadFields(null, slotDesc); // skip field values
+                } else if (slotDesc.hasReadObjectMethod()) {
                     SerialCallbackContext oldContext = curContext;
-
+                    if (oldContext != null)
+                        oldContext.check();
                     try {
                         curContext = new SerialCallbackContext(obj, slotDesc);
 
@@ -1903,6 +1912,8 @@
                         handles.markException(passHandle, ex);
                     } finally {
                         curContext.setUsed();
+                        if (oldContext!= null)
+                            oldContext.check();
                         curContext = oldContext;
                     }
 
@@ -1915,6 +1926,7 @@
                 } else {
                     defaultReadFields(obj, slotDesc);
                 }
+
                 if (slotDesc.hasWriteObjectData()) {
                     skipCustomData();
                 } else {
@@ -1968,8 +1980,7 @@
     private void defaultReadFields(Object obj, ObjectStreamClass desc)
         throws IOException
     {
-        // REMIND: is isInstance check necessary?
-        Class cl = desc.forClass();
+        Class<?> cl = desc.forClass();
         if (cl != null && obj != null && !cl.isInstance(obj)) {
             throw new ClassCastException();
         }
@@ -2172,7 +2183,7 @@
          * class descriptor, returns -1.  Throws IllegalArgumentException if
          * neither incoming nor local class descriptor contains a match.
          */
-        private int getFieldOffset(String name, Class type) {
+        private int getFieldOffset(String name, Class<?> type) {
             ObjectStreamField field = desc.getField(name, type);
             if (field != null) {
                 return field.getOffset();
@@ -2870,6 +2881,7 @@
             return readUTFBody(readUnsignedShort());
         }
 
+        @SuppressWarnings("deprecation")
         public String readLine() throws IOException {
             return din.readLine();      // deprecated, not worth optimizing
         }
diff --git a/ojluni/src/main/java/java/io/ObjectOutputStream.java b/ojluni/src/main/java/java/io/ObjectOutputStream.java
index f2abe23..1503112 100644
--- a/ojluni/src/main/java/java/io/ObjectOutputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectOutputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -264,6 +264,7 @@
      * @throws  SecurityException if a security manager exists and its
      *          <code>checkPermission</code> method denies enabling
      *          subclassing.
+     * @throws  IOException if an I/O error occurs while creating this stream
      * @see SecurityManager#checkPermission
      * @see java.io.SerializablePermission
      */
@@ -445,11 +446,12 @@
      *          <code>OutputStream</code>
      */
     public void defaultWriteObject() throws IOException {
-        if ( curContext == null ) {
+        SerialCallbackContext ctx = curContext;
+        if (ctx == null) {
             throw new NotActiveException("not in call to writeObject");
         }
-        Object curObj = curContext.getObj();
-        ObjectStreamClass curDesc = curContext.getDesc();
+        Object curObj = ctx.getObj();
+        ObjectStreamClass curDesc = ctx.getDesc();
         bout.setBlockDataMode(false);
         defaultWriteFields(curObj, curDesc);
         bout.setBlockDataMode(true);
@@ -467,11 +469,12 @@
      */
     public ObjectOutputStream.PutField putFields() throws IOException {
         if (curPut == null) {
-            if (curContext == null) {
+            SerialCallbackContext ctx = curContext;
+            if (ctx == null) {
                 throw new NotActiveException("not in call to writeObject");
             }
-            Object curObj = curContext.getObj();
-            ObjectStreamClass curDesc = curContext.getDesc();
+            Object curObj = ctx.getObj();
+            ObjectStreamClass curDesc = ctx.getDesc();
             curPut = new PutFieldImpl(curDesc);
         }
         return curPut;
@@ -500,7 +503,7 @@
      * stream.  The state is reset to be the same as a new ObjectOutputStream.
      * The current point in the stream is marked as reset so the corresponding
      * ObjectInputStream will be reset at the same point.  Objects previously
-     * written to the stream will not be refered to as already being in the
+     * written to the stream will not be referred to as already being in the
      * stream.  They will be written to the stream again.
      *
      * @throws  IOException if reset() is invoked while serializing an object.
@@ -1051,7 +1054,7 @@
      * "enableSubclassImplementation" SerializablePermission is checked.
      */
     private void verifySubclass() {
-        Class cl = getClass();
+        Class<?> cl = getClass();
         if (cl == ObjectOutputStream.class) {
             return;
         }
@@ -1077,22 +1080,22 @@
      * override security-sensitive non-final methods.  Returns true if subclass
      * is "safe", false otherwise.
      */
-    private static boolean auditSubclass(final Class subcl) {
+    private static boolean auditSubclass(final Class<?> subcl) {
         Boolean result = AccessController.doPrivileged(
             new PrivilegedAction<Boolean>() {
                 public Boolean run() {
-                    for (Class cl = subcl;
+                    for (Class<?> cl = subcl;
                          cl != ObjectOutputStream.class;
                          cl = cl.getSuperclass())
                     {
                         try {
                             cl.getDeclaredMethod(
-                                "writeUnshared", new Class[] { Object.class });
+                                "writeUnshared", new Class<?>[] { Object.class });
                             return Boolean.FALSE;
                         } catch (NoSuchMethodException ex) {
                         }
                         try {
-                            cl.getDeclaredMethod("putFields", (Class[]) null);
+                            cl.getDeclaredMethod("putFields", (Class<?>[]) null);
                             return Boolean.FALSE;
                         } catch (NoSuchMethodException ex) {
                         }
@@ -1141,13 +1144,13 @@
 
             // check for replacement object
             Object orig = obj;
-            Class cl = obj.getClass();
+            Class<?> cl = obj.getClass();
             ObjectStreamClass desc;
 
             /* ----- BEGIN android -----
             for (;;) {
                 // REMIND: skip this check for strings/arrays?
-                Class repCl;
+                Class<?> repCl;
                 desc = ObjectStreamClass.lookup(cl, true);
                 if (!desc.hasWriteReplaceMethod() ||
                     (obj = desc.invokeWriteReplace(obj)) == null ||
@@ -1213,7 +1216,7 @@
             } else if (cl.isArray()) {
                 writeArray(obj, desc, unshared);
             } else if (obj instanceof Enum) {
-                writeEnum((Enum) obj, desc, unshared);
+                writeEnum((Enum<?>) obj, desc, unshared);
             } else if (obj instanceof Serializable) {
                 writeOrdinaryObject(obj, desc, unshared);
             } else {
@@ -1248,7 +1251,7 @@
     /**
      * Writes representation of given class to stream.
      */
-    private void writeClass(Class cl, boolean unshared) throws IOException {
+    private void writeClass(Class<?> cl, boolean unshared) throws IOException {
         bout.writeByte(TC_CLASS);
         writeClassDesc(ObjectStreamClass.lookup(cl, true), false);
         handles.assign(unshared ? null : cl);
@@ -1287,15 +1290,15 @@
         bout.writeByte(TC_PROXYCLASSDESC);
         handles.assign(unshared ? null : desc);
 
-        Class cl = desc.forClass();
-        Class[] ifaces = cl.getInterfaces();
+        Class<?> cl = desc.forClass();
+        Class<?>[] ifaces = cl.getInterfaces();
         bout.writeInt(ifaces.length);
         for (int i = 0; i < ifaces.length; i++) {
             bout.writeUTF(ifaces[i].getName());
         }
 
         bout.setBlockDataMode(true);
-        if (isCustomSubclass()) {
+        if (cl != null && isCustomSubclass()) {
             ReflectUtil.checkPackageAccess(cl);
         }
         annotateProxyClass(cl);
@@ -1322,9 +1325,9 @@
             writeClassDescriptor(desc);
         }
 
-        Class cl = desc.forClass();
+        Class<?> cl = desc.forClass();
         bout.setBlockDataMode(true);
-        if (isCustomSubclass()) {
+        if (cl != null && isCustomSubclass()) {
             ReflectUtil.checkPackageAccess(cl);
         }
         annotateClass(cl);
@@ -1362,7 +1365,7 @@
         writeClassDesc(desc, false);
         handles.assign(unshared ? null : array);
 
-        Class ccl = desc.forClass().getComponentType();
+        Class<?> ccl = desc.forClass().getComponentType();
         if (ccl.isPrimitive()) {
             if (ccl == Integer.TYPE) {
                 int[] ia = (int[]) array;
@@ -1433,7 +1436,7 @@
     /**
      * Writes given enum constant to stream.
      */
-    private void writeEnum(Enum en,
+    private void writeEnum(Enum<?> en,
                            ObjectStreamClass desc,
                            boolean unshared)
         throws IOException
@@ -1559,7 +1562,11 @@
     private void defaultWriteFields(Object obj, ObjectStreamClass desc)
         throws IOException
     {
-        // REMIND: perform conservative isInstance check here?
+        Class<?> cl = desc.forClass();
+        if (cl != null && obj != null && !cl.isInstance(obj)) {
+            throw new ClassCastException();
+        }
+
         desc.checkDefaultSerialize();
 
         int primDataSize = desc.getPrimDataSize();
@@ -1756,7 +1763,7 @@
          * types, and any other non-null type matches assignable types only.
          * Throws IllegalArgumentException if no matching field found.
          */
-        private int getFieldOffset(String name, Class type) {
+        private int getFieldOffset(String name, Class<?> type) {
             ObjectStreamField field = desc.getField(name, type);
             if (field == null) {
                 throw new IllegalArgumentException("no such field " + name +
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index 08096c4..ff1cf82 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -169,7 +169,7 @@
     private volatile ClassDataSlot[] dataLayout;
 
     /** serialization-appropriate constructor, or null if none */
-    private Constructor cons;
+    private Constructor<?> cons;
     /** class-defined writeObject method, or null if none */
     private Method writeObjectMethod;
     /** class-defined readObject method, or null if none */
@@ -506,7 +506,7 @@
             fieldRefl = getReflector(fields, this);
         } catch (InvalidClassException ex) {
             // field mismatches impossible when matching local fields vs. self
-            throw new InternalError();
+            throw new InternalError(ex);
         }
 
         if (deserializeEx == null) {
@@ -956,7 +956,7 @@
                 return cons.newInstance();
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
-                throw new InternalError();
+                throw new InternalError(ex);
             }
         } else {
             throw new UnsupportedOperationException();
@@ -984,7 +984,7 @@
                 }
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
-                throw new InternalError();
+                throw new InternalError(ex);
             }
         } else {
             throw new UnsupportedOperationException();
@@ -1015,7 +1015,7 @@
                 }
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
-                throw new InternalError();
+                throw new InternalError(ex);
             }
         } else {
             throw new UnsupportedOperationException();
@@ -1043,7 +1043,7 @@
                 }
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
-                throw new InternalError();
+                throw new InternalError(ex);
             }
         } else {
             throw new UnsupportedOperationException();
@@ -1068,11 +1068,11 @@
                     throw (ObjectStreamException) th;
                 } else {
                     throwMiscException(th);
-                    throw new InternalError();  // never reached
+                    throw new InternalError(th);  // never reached
                 }
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
-                throw new InternalError();
+                throw new InternalError(ex);
             }
         } else {
             throw new UnsupportedOperationException();
@@ -1097,11 +1097,11 @@
                     throw (ObjectStreamException) th;
                 } else {
                     throwMiscException(th);
-                    throw new InternalError();  // never reached
+                    throw new InternalError(th);  // never reached
                 }
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
-                throw new InternalError();
+                throw new InternalError(ex);
             }
         } else {
             throw new UnsupportedOperationException();
@@ -1330,9 +1330,9 @@
      * Access checks are disabled on the returned constructor (if any), since
      * the defining class may still be non-public.
      */
-    private static Constructor getExternalizableConstructor(Class<?> cl) {
+    private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
         try {
-            Constructor cons = cl.getDeclaredConstructor((Class<?>[]) null);
+            Constructor<?> cons = cl.getDeclaredConstructor((Class<?>[]) null);
             cons.setAccessible(true);
             return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
                 cons : null;
@@ -1346,7 +1346,7 @@
      * superclass, or null if none found.  Access checks are disabled on the
      * returned constructor (if any).
      */
-    private static Constructor getSerializableConstructor(Class<?> cl) {
+    private static Constructor<?> getSerializableConstructor(Class<?> cl) {
         Class<?> initCl = cl;
         while (Serializable.class.isAssignableFrom(initCl)) {
             if ((initCl = initCl.getSuperclass()) == null) {
@@ -1354,7 +1354,7 @@
             }
         }
         try {
-            Constructor cons = initCl.getDeclaredConstructor((Class<?>[]) null);
+            Constructor<?> cons = initCl.getDeclaredConstructor((Class<?>[]) null);
             int mods = cons.getModifiers();
             if ((mods & Modifier.PRIVATE) != 0 ||
                 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
@@ -1739,7 +1739,7 @@
                 dout.writeUTF("()V");
             }
 
-            Constructor[] cons = cl.getDeclaredConstructors();
+            Constructor<?>[] cons = cl.getDeclaredConstructors();
             MemberSignature[] consSigs = new MemberSignature[cons.length];
             for (int i = 0; i < cons.length; i++) {
                 consSigs[i] = new MemberSignature(cons[i]);
@@ -1800,7 +1800,7 @@
             }
             return hash;
         } catch (IOException ex) {
-            throw new InternalError();
+            throw new InternalError(ex);
         } catch (NoSuchAlgorithmException ex) {
             throw new SecurityException(ex.getMessage());
         }
@@ -1834,7 +1834,7 @@
             signature = getClassSignature(field.getType());
         }
 
-        public MemberSignature(Constructor cons) {
+        public MemberSignature(Constructor<?> cons) {
             member = cons;
             name = cons.getName();
             signature = getMethodSignature(
diff --git a/ojluni/src/main/java/java/io/ObjectStreamConstants.java b/ojluni/src/main/java/java/io/ObjectStreamConstants.java
index ddbada9..23f72b4 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamConstants.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -219,7 +219,7 @@
     * This protocol is written by JVM 1.2.
     *
     * Externalizable data is written in block data mode and is
-    * terminated with TC_ENDBLOCKDATA. Externalizable classdescriptor
+    * terminated with TC_ENDBLOCKDATA. Externalizable class descriptor
     * flags has SC_BLOCK_DATA enabled. JVM 1.1.6 and greater can
     * read this format change.
     *
diff --git a/ojluni/src/main/java/java/io/ObjectStreamField.java b/ojluni/src/main/java/java/io/ObjectStreamField.java
index 0eee71f..c49bcac 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamField.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamField.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -235,6 +235,8 @@
      * Returns boolean value indicating whether or not the serializable field
      * represented by this ObjectStreamField instance is unshared.
      *
+     * @return {@code true} if this field is unshared
+     *
      * @since 1.4
      */
     public boolean isUnshared() {
diff --git a/ojluni/src/main/java/java/io/OutputStreamWriter.java b/ojluni/src/main/java/java/io/OutputStreamWriter.java
index b4e4b9e..5f7b9e3 100644
--- a/ojluni/src/main/java/java/io/OutputStreamWriter.java
+++ b/ojluni/src/main/java/java/io/OutputStreamWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 /**
  * An OutputStreamWriter is a bridge from character streams to byte streams:
  * Characters written to it are encoded into bytes using a specified {@link
- * java.nio.charset.Charset <code>charset</code>}.  The charset that it uses
+ * java.nio.charset.Charset charset}.  The charset that it uses
  * may be specified by name or may be given explicitly, or the platform's
  * default charset may be accepted.
  *
@@ -86,7 +86,7 @@
      *
      * @param  charsetName
      *         The name of a supported
-     *         {@link java.nio.charset.Charset </code>charset<code>}
+     *         {@link java.nio.charset.Charset charset}
      *
      * @exception  UnsupportedEncodingException
      *             If the named encoding is not supported
@@ -115,7 +115,7 @@
     }
 
     /**
-     * Creates an OutputStreamWriter that uses the given charset. </p>
+     * Creates an OutputStreamWriter that uses the given charset.
      *
      * @param  out
      *         An OutputStream
@@ -134,7 +134,7 @@
     }
 
     /**
-     * Creates an OutputStreamWriter that uses the given charset encoder.  </p>
+     * Creates an OutputStreamWriter that uses the given charset encoder.
      *
      * @param  out
      *         An OutputStream
diff --git a/ojluni/src/main/java/java/io/PipedInputStream.java b/ojluni/src/main/java/java/io/PipedInputStream.java
index 66cf19d..d7fb790 100644
--- a/ojluni/src/main/java/java/io/PipedInputStream.java
+++ b/ojluni/src/main/java/java/io/PipedInputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
  * The piped input stream contains a buffer,
  * decoupling read operations from write operations,
  * within limits.
- * A pipe is said to be <a name=BROKEN> <i>broken</i> </a> if a
+ * A pipe is said to be <a name="BROKEN"> <i>broken</i> </a> if a
  * thread that was providing data bytes to the connected
  * piped output stream is no longer alive.
  *
@@ -123,7 +123,7 @@
      * @param      src   the stream to connect to.
      * @param      pipeSize the size of the pipe's buffer.
      * @exception  IOException  if an I/O error occurs.
-     * @exception  IllegalArgumentException if <code>pipeSize <= 0</code>.
+     * @exception  IllegalArgumentException if {@code pipeSize <= 0}.
      * @since      1.6
      */
     public PipedInputStream(PipedOutputStream src, int pipeSize)
@@ -153,7 +153,7 @@
      * connected} to a <code>PipedOutputStream</code> before being used.
      *
      * @param      pipeSize the size of the pipe's buffer.
-     * @exception  IllegalArgumentException if <code>pipeSize <= 0</code>.
+     * @exception  IllegalArgumentException if {@code pipeSize <= 0}.
      * @since      1.6
      */
     public PipedInputStream(int pipeSize) {
@@ -178,15 +178,14 @@
      * unconnected piped output stream and <code>snk</code>
      * is an unconnected piped input stream, they
      * may be connected by either the call:
-     * <p>
+     *
      * <pre><code>snk.connect(src)</code> </pre>
      * <p>
      * or the call:
-     * <p>
+     *
      * <pre><code>src.connect(snk)</code> </pre>
      * <p>
-     * The two
-     * calls have the same effect.
+     * The two calls have the same effect.
      *
      * @param      src   The piped output stream to connect to.
      * @exception  IOException  if an I/O error occurs.
@@ -199,7 +198,7 @@
      * Receives a byte of data.  This method will block if no input is
      * available.
      * @param b the byte being received
-     * @exception IOException If the pipe is <a href=#BROKEN> <code>broken</code></a>,
+     * @exception IOException If the pipe is <a href="#BROKEN"> <code>broken</code></a>,
      *          {@link #connect(java.io.PipedOutputStream) unconnected},
      *          closed, or if an I/O error occurs.
      * @since     JDK1.1
@@ -225,7 +224,7 @@
      * @param b the buffer into which the data is received
      * @param off the start offset of the data
      * @param len the maximum number of bytes received
-     * @exception IOException If the pipe is <a href=#BROKEN> broken</a>,
+     * @exception IOException If the pipe is <a href="#BROKEN"> broken</a>,
      *           {@link #connect(java.io.PipedOutputStream) unconnected},
      *           closed,or if an I/O error occurs.
      */
@@ -309,7 +308,7 @@
      *             stream is reached.
      * @exception  IOException  if the pipe is
      *           {@link #connect(java.io.PipedOutputStream) unconnected},
-     *           <a href=#BROKEN> <code>broken</code></a>, closed,
+     *           <a href="#BROKEN"> <code>broken</code></a>, closed,
      *           or if an I/O error occurs.
      */
     public synchronized int read()  throws IOException {
@@ -377,7 +376,7 @@
      * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
      * <code>len</code> is negative, or <code>len</code> is greater than
      * <code>b.length - off</code>
-     * @exception  IOException if the pipe is <a href=#BROKEN> <code>broken</code></a>,
+     * @exception  IOException if the pipe is <a href="#BROKEN"> <code>broken</code></a>,
      *           {@link #connect(java.io.PipedOutputStream) unconnected},
      *           closed, or if an I/O error occurs.
      */
@@ -435,7 +434,7 @@
      *         without blocking, or {@code 0} if this input stream has been
      *         closed by invoking its {@link #close()} method, or if the pipe
      *         is {@link #connect(java.io.PipedOutputStream) unconnected}, or
-     *          <a href=#BROKEN> <code>broken</code></a>.
+     *          <a href="#BROKEN"> <code>broken</code></a>.
      *
      * @exception  IOException  if an I/O error occurs.
      * @since   JDK1.0.2
diff --git a/ojluni/src/main/java/java/io/PipedReader.java b/ojluni/src/main/java/java/io/PipedReader.java
index 93b7205..e4ec566 100644
--- a/ojluni/src/main/java/java/io/PipedReader.java
+++ b/ojluni/src/main/java/java/io/PipedReader.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,7 +96,7 @@
      * @param      src       the stream to connect to.
      * @param      pipeSize  the size of the pipe's buffer.
      * @exception  IOException  if an I/O error occurs.
-     * @exception  IllegalArgumentException if <code>pipeSize <= 0</code>.
+     * @exception  IllegalArgumentException if {@code pipeSize <= 0}.
      * @since      1.6
      */
     public PipedReader(PipedWriter src, int pipeSize) throws IOException {
@@ -125,7 +125,7 @@
      * before being used.
      *
      * @param   pipeSize the size of the pipe's buffer.
-     * @exception  IllegalArgumentException if <code>pipeSize <= 0</code>.
+     * @exception  IllegalArgumentException if {@code pipeSize <= 0}.
      * @since      1.6
      */
     public PipedReader(int pipeSize) {
@@ -150,15 +150,14 @@
      * unconnected piped writer and <code>snk</code>
      * is an unconnected piped reader, they
      * may be connected by either the call:
-     * <p>
+     *
      * <pre><code>snk.connect(src)</code> </pre>
      * <p>
      * or the call:
-     * <p>
+     *
      * <pre><code>src.connect(snk)</code> </pre>
      * <p>
-     * The two
-     * calls have the same effect.
+     * The two calls have the same effect.
      *
      * @param      src   The piped writer to connect to.
      * @exception  IOException  if an I/O error occurs.
diff --git a/ojluni/src/main/java/java/io/PrintStream.java b/ojluni/src/main/java/java/io/PrintStream.java
index 6968527..08bb3a3 100644
--- a/ojluni/src/main/java/java/io/PrintStream.java
+++ b/ojluni/src/main/java/java/io/PrintStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -302,7 +302,7 @@
      *          creating the file
      *
      * @throws  SecurityException
-     *          If a security manager is presentand {@link
+     *          If a security manager is present and {@link
      *          SecurityManager#checkWrite checkWrite(file.getPath())}
      *          denies write access to the file
      *
@@ -869,7 +869,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
@@ -919,7 +919,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
@@ -962,7 +962,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
@@ -1019,7 +1019,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
diff --git a/ojluni/src/main/java/java/io/PrintWriter.java b/ojluni/src/main/java/java/io/PrintWriter.java
index 102c3a2..9287a19 100644
--- a/ojluni/src/main/java/java/io/PrintWriter.java
+++ b/ojluni/src/main/java/java/io/PrintWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -784,7 +784,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
@@ -835,7 +835,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
@@ -879,7 +879,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
@@ -939,7 +939,7 @@
      *         <tt>null</tt> argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
-     * @throws  IllegalFormatException
+     * @throws  java.util.IllegalFormatException
      *          If a format string contains an illegal syntax, a format
      *          specifier that is incompatible with the given arguments,
      *          insufficient arguments given the format string, or other
diff --git a/ojluni/src/main/java/java/io/PushbackInputStream.java b/ojluni/src/main/java/java/io/PushbackInputStream.java
index af0b525..b44848d 100644
--- a/ojluni/src/main/java/java/io/PushbackInputStream.java
+++ b/ojluni/src/main/java/java/io/PushbackInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,7 @@
      *
      * @param  in    the input stream from which bytes will be read.
      * @param  size  the size of the pushback buffer.
-     * @exception IllegalArgumentException if size is <= 0
+     * @exception IllegalArgumentException if {@code size <= 0}
      * @since  JDK1.1
      */
     public PushbackInputStream(InputStream in, int size) {
diff --git a/ojluni/src/main/java/java/io/PushbackReader.java b/ojluni/src/main/java/java/io/PushbackReader.java
index 2f5b18c..f918621 100644
--- a/ojluni/src/main/java/java/io/PushbackReader.java
+++ b/ojluni/src/main/java/java/io/PushbackReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
      *
      * @param   in   The reader from which characters will be read
      * @param   size The size of the pushback buffer
-     * @exception IllegalArgumentException if size is <= 0
+     * @exception IllegalArgumentException if {@code size <= 0}
      */
     public PushbackReader(Reader in, int size) {
         super(in);
diff --git a/ojluni/src/main/java/java/io/Reader.java b/ojluni/src/main/java/java/io/Reader.java
index e2248c4..1c9cca6 100644
--- a/ojluni/src/main/java/java/io/Reader.java
+++ b/ojluni/src/main/java/java/io/Reader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@
      *         -1 if this source of characters is at its end
      * @throws IOException if an I/O error occurs
      * @throws NullPointerException if target is null
-     * @throws ReadOnlyBufferException if target is a read only buffer
+     * @throws java.nio.ReadOnlyBufferException if target is a read only buffer
      * @since 1.5
      */
     public int read(java.nio.CharBuffer target) throws IOException {
diff --git a/ojluni/src/main/java/java/io/SequenceInputStream.java b/ojluni/src/main/java/java/io/SequenceInputStream.java
index f64ec38..01da7f6 100644
--- a/ojluni/src/main/java/java/io/SequenceInputStream.java
+++ b/ojluni/src/main/java/java/io/SequenceInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
  */
 public
 class SequenceInputStream extends InputStream {
-    Enumeration e;
+    Enumeration<? extends InputStream> e;
     InputStream in;
 
     /**
@@ -85,7 +85,7 @@
      * @param   s2   the second input stream to read.
      */
     public SequenceInputStream(InputStream s1, InputStream s2) {
-        Vector  v = new Vector(2);
+        Vector<InputStream> v = new Vector<>(2);
 
         v.addElement(s1);
         v.addElement(s2);
@@ -135,7 +135,7 @@
      * @since   JDK1.1
      */
     public int available() throws IOException {
-        if(in == null) {
+        if (in == null) {
             return 0; // no way to signal EOF from available()
         }
         return in.available();
@@ -160,15 +160,14 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public int read() throws IOException {
-        if (in == null) {
-            return -1;
-        }
-        int c = in.read();
-        if (c == -1) {
+        while (in != null) {
+            int c = in.read();
+            if (c != -1) {
+                return c;
+            }
             nextStream();
-            return read();
         }
-        return c;
+        return -1;
     }
 
     /**
@@ -204,13 +203,14 @@
         } else if (len == 0) {
             return 0;
         }
-
-        int n = in.read(b, off, len);
-        if (n <= 0) {
+        do {
+            int n = in.read(b, off, len);
+            if (n > 0) {
+                return n;
+            }
             nextStream();
-            return read(b, off, len);
-        }
-        return n;
+        } while (in != null);
+        return -1;
     }
 
     /**
diff --git a/ojluni/src/main/java/java/io/SerialCallbackContext.java b/ojluni/src/main/java/java/io/SerialCallbackContext.java
index 748d38e..4009087 100644
--- a/ojluni/src/main/java/java/io/SerialCallbackContext.java
+++ b/ojluni/src/main/java/java/io/SerialCallbackContext.java
@@ -60,6 +60,13 @@
         return desc;
     }
 
+    public void check() throws NotActiveException {
+        if (thread != null && thread != Thread.currentThread()) {
+            throw new NotActiveException(
+                "expected thread: " + thread + ", but got: " + Thread.currentThread());
+        }
+    }
+
     private void checkAndSetUsed() throws NotActiveException {
         if (thread != Thread.currentThread()) {
              throw new NotActiveException(
diff --git a/ojluni/src/main/java/java/io/Serializable.java b/ojluni/src/main/java/java/io/Serializable.java
index 83bfe03..96ea33c 100644
--- a/ojluni/src/main/java/java/io/Serializable.java
+++ b/ojluni/src/main/java/java/io/Serializable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,7 @@
  *
  * Classes that require special handling during the serialization and
  * deserialization process must implement special methods with these exact
- * signatures: <p>
+ * signatures:
  *
  * <PRE>
  * private void writeObject(java.io.ObjectOutputStream out)
@@ -101,7 +101,7 @@
  *
  * <p>Serializable classes that need to designate an alternative object to be
  * used when writing an object to the stream should implement this
- * special method with the exact signature: <p>
+ * special method with the exact signature:
  *
  * <PRE>
  * ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
@@ -115,7 +115,7 @@
  *
  * Classes that need to designate a replacement when an instance of it
  * is read from the stream should implement this special method with the
- * exact signature.<p>
+ * exact signature.
  *
  * <PRE>
  * ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
@@ -133,7 +133,7 @@
  * deserialization will result in an {@link InvalidClassException}.  A
  * serializable class can declare its own serialVersionUID explicitly by
  * declaring a field named <code>"serialVersionUID"</code> that must be static,
- * final, and of type <code>long</code>:<p>
+ * final, and of type <code>long</code>:
  *
  * <PRE>
  * ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
diff --git a/ojluni/src/main/java/java/io/SerializablePermission.java b/ojluni/src/main/java/java/io/SerializablePermission.java
index ab1ccf4..e11f3ee 100644
--- a/ojluni/src/main/java/java/io/SerializablePermission.java
+++ b/ojluni/src/main/java/java/io/SerializablePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/io/StreamTokenizer.java b/ojluni/src/main/java/java/io/StreamTokenizer.java
index 81ec5d5..3c7c7cc 100644
--- a/ojluni/src/main/java/java/io/StreamTokenizer.java
+++ b/ojluni/src/main/java/java/io/StreamTokenizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 import java.util.Arrays;
 
 /**
- * The <code>StreamTokenizer</code> class takes an input stream and
+ * The {@code StreamTokenizer} class takes an input stream and
  * parses it into "tokens", allowing the tokens to be
  * read one at a time. The parsing process is controlled by a table
  * and a number of flags that can be set to various states. The
@@ -36,7 +36,7 @@
  * strings, and various comment styles.
  * <p>
  * Each byte read from the input stream is regarded as a character
- * in the range <code>'&#92;u0000'</code> through <code>'&#92;u00FF'</code>.
+ * in the range {@code '\u005Cu0000'} through {@code '\u005Cu00FF'}.
  * The character value is used to look up five possible attributes of
  * the character: <i>white space</i>, <i>alphabetic</i>,
  * <i>numeric</i>, <i>string quote</i>, and <i>comment character</i>.
@@ -53,8 +53,8 @@
  * <p>
  * A typical application first constructs an instance of this class,
  * sets up the syntax tables, and then repeatedly loops calling the
- * <code>nextToken</code> method in each iteration of the loop until
- * it returns the value <code>TT_EOF</code>.
+ * {@code nextToken} method in each iteration of the loop until
+ * it returns the value {@code TT_EOF}.
  *
  * @author  James Gosling
  * @see     java.io.StreamTokenizer#nextToken()
@@ -99,19 +99,19 @@
     private static final byte CT_COMMENT = 16;
 
     /**
-     * After a call to the <code>nextToken</code> method, this field
+     * After a call to the {@code nextToken} method, this field
      * contains the type of the token just read. For a single character
      * token, its value is the single character, converted to an integer.
      * For a quoted string token, its value is the quote character.
      * Otherwise, its value is one of the following:
      * <ul>
-     * <li><code>TT_WORD</code> indicates that the token is a word.
-     * <li><code>TT_NUMBER</code> indicates that the token is a number.
-     * <li><code>TT_EOL</code> indicates that the end of line has been read.
+     * <li>{@code TT_WORD} indicates that the token is a word.
+     * <li>{@code TT_NUMBER} indicates that the token is a number.
+     * <li>{@code TT_EOL} indicates that the end of line has been read.
      *     The field can only have this value if the
-     *     <code>eolIsSignificant</code> method has been called with the
-     *     argument <code>true</code>.
-     * <li><code>TT_EOF</code> indicates that the end of the input stream
+     *     {@code eolIsSignificant} method has been called with the
+     *     argument {@code true}.
+     * <li>{@code TT_EOF} indicates that the end of the input stream
      *     has been reached.
      * </ul>
      * <p>
@@ -160,8 +160,8 @@
      * the string.
      * <p>
      * The current token is a word when the value of the
-     * <code>ttype</code> field is <code>TT_WORD</code>. The current token is
-     * a quoted string token when the value of the <code>ttype</code> field is
+     * {@code ttype} field is {@code TT_WORD}. The current token is
+     * a quoted string token when the value of the {@code ttype} field is
      * a quote character.
      * <p>
      * The initial value of this field is null.
@@ -175,7 +175,7 @@
     /**
      * If the current token is a number, this field contains the value
      * of that number. The current token is a number when the value of
-     * the <code>ttype</code> field is <code>TT_NUMBER</code>.
+     * the {@code ttype} field is {@code TT_NUMBER}.
      * <p>
      * The initial value of this field is 0.0.
      *
@@ -201,14 +201,14 @@
      * stream. The stream tokenizer is initialized to the following
      * default state:
      * <ul>
-     * <li>All byte values <code>'A'</code> through <code>'Z'</code>,
-     *     <code>'a'</code> through <code>'z'</code>, and
-     *     <code>'&#92;u00A0'</code> through <code>'&#92;u00FF'</code> are
+     * <li>All byte values {@code 'A'} through {@code 'Z'},
+     *     {@code 'a'} through {@code 'z'}, and
+     *     {@code '\u005Cu00A0'} through {@code '\u005Cu00FF'} are
      *     considered to be alphabetic.
-     * <li>All byte values <code>'&#92;u0000'</code> through
-     *     <code>'&#92;u0020'</code> are considered to be white space.
-     * <li><code>'/'</code> is a comment character.
-     * <li>Single quote <code>'&#92;''</code> and double quote <code>'"'</code>
+     * <li>All byte values {@code '\u005Cu0000'} through
+     *     {@code '\u005Cu0020'} are considered to be white space.
+     * <li>{@code '/'} is a comment character.
+     * <li>Single quote {@code '\u005C''} and double quote {@code '"'}
      *     are string quote characters.
      * <li>Numbers are parsed.
      * <li>Ends of lines are treated as white space, not as separate tokens.
@@ -252,7 +252,7 @@
 
     /**
      * Resets this tokenizer's syntax table so that all characters are
-     * "ordinary." See the <code>ordinaryChar</code> method
+     * "ordinary." See the {@code ordinaryChar} method
      * for more information on a character being ordinary.
      *
      * @see     java.io.StreamTokenizer#ordinaryChar(int)
@@ -305,7 +305,7 @@
      * Specifies that all characters <i>c</i> in the range
      * <code>low&nbsp;&lt;=&nbsp;<i>c</i>&nbsp;&lt;=&nbsp;high</code>
      * are "ordinary" in this tokenizer. See the
-     * <code>ordinaryChar</code> method for more information on a
+     * {@code ordinaryChar} method for more information on a
      * character being ordinary.
      *
      * @param   low   the low end of the range.
@@ -327,12 +327,12 @@
      * character has as a comment character, word component, string
      * delimiter, white space, or number character. When such a character
      * is encountered by the parser, the parser treats it as a
-     * single-character token and sets <code>ttype</code> field to the
+     * single-character token and sets {@code ttype} field to the
      * character value.
      *
      * <p>Making a line terminator character "ordinary" may interfere
-     * with the ability of a <code>StreamTokenizer</code> to count
-     * lines. The <code>lineno</code> method may no longer reflect
+     * with the ability of a {@code StreamTokenizer} to count
+     * lines. The {@code lineno} method may no longer reflect
      * the presence of such terminator characters in its line count.
      *
      * @param   ch   the character.
@@ -361,9 +361,9 @@
      * Specifies that matching pairs of this character delimit string
      * constants in this tokenizer.
      * <p>
-     * When the <code>nextToken</code> method encounters a string
-     * constant, the <code>ttype</code> field is set to the string
-     * delimiter and the <code>sval</code> field is set to the body of
+     * When the {@code nextToken} method encounters a string
+     * constant, the {@code ttype} field is set to the string
+     * delimiter and the {@code sval} field is set to the body of
      * the string.
      * <p>
      * If a string quote character is encountered, then a string is
@@ -371,7 +371,7 @@
      * the string quote character, up to (but not including) the next
      * occurrence of that same string quote character, or a line
      * terminator, or end of file. The usual escape sequences such as
-     * <code>"&#92;n"</code> and <code>"&#92;t"</code> are recognized and
+     * {@code "\u005Cn"} and {@code "\u005Ct"} are recognized and
      * converted to single characters as the string is parsed.
      *
      * <p>Any other attribute settings for the specified character are cleared.
@@ -398,9 +398,9 @@
      * <p>
      * When the parser encounters a word token that has the format of a
      * double precision floating-point number, it treats the token as a
-     * number rather than a word, by setting the <code>ttype</code>
-     * field to the value <code>TT_NUMBER</code> and putting the numeric
-     * value of the token into the <code>nval</code> field.
+     * number rather than a word, by setting the {@code ttype}
+     * field to the value {@code TT_NUMBER} and putting the numeric
+     * value of the token into the {@code nval} field.
      *
      * @see     java.io.StreamTokenizer#nval
      * @see     java.io.StreamTokenizer#TT_NUMBER
@@ -416,21 +416,21 @@
     /**
      * Determines whether or not ends of line are treated as tokens.
      * If the flag argument is true, this tokenizer treats end of lines
-     * as tokens; the <code>nextToken</code> method returns
-     * <code>TT_EOL</code> and also sets the <code>ttype</code> field to
+     * as tokens; the {@code nextToken} method returns
+     * {@code TT_EOL} and also sets the {@code ttype} field to
      * this value when an end of line is read.
      * <p>
      * A line is a sequence of characters ending with either a
-     * carriage-return character (<code>'&#92;r'</code>) or a newline
-     * character (<code>'&#92;n'</code>). In addition, a carriage-return
+     * carriage-return character ({@code '\u005Cr'}) or a newline
+     * character ({@code '\u005Cn'}). In addition, a carriage-return
      * character followed immediately by a newline character is treated
      * as a single end-of-line token.
      * <p>
-     * If the <code>flag</code> is false, end-of-line characters are
+     * If the {@code flag} is false, end-of-line characters are
      * treated as white space and serve only to separate tokens.
      *
-     * @param   flag   <code>true</code> indicates that end-of-line characters
-     *                 are separate tokens; <code>false</code> indicates that
+     * @param   flag   {@code true} indicates that end-of-line characters
+     *                 are separate tokens; {@code false} indicates that
      *                 end-of-line characters are white space.
      * @see     java.io.StreamTokenizer#nextToken()
      * @see     java.io.StreamTokenizer#ttype
@@ -442,14 +442,14 @@
 
     /**
      * Determines whether or not the tokenizer recognizes C-style comments.
-     * If the flag argument is <code>true</code>, this stream tokenizer
+     * If the flag argument is {@code true}, this stream tokenizer
      * recognizes C-style comments. All text between successive
-     * occurrences of <code>/*</code> and <code>*&#47;</code> are discarded.
+     * occurrences of {@code /*} and <code>*&#47;</code> are discarded.
      * <p>
-     * If the flag argument is <code>false</code>, then C-style comments
+     * If the flag argument is {@code false}, then C-style comments
      * are not treated specially.
      *
-     * @param   flag   <code>true</code> indicates to recognize and ignore
+     * @param   flag   {@code true} indicates to recognize and ignore
      *                 C-style comments.
      */
     public void slashStarComments(boolean flag) {
@@ -458,15 +458,15 @@
 
     /**
      * Determines whether or not the tokenizer recognizes C++-style comments.
-     * If the flag argument is <code>true</code>, this stream tokenizer
+     * If the flag argument is {@code true}, this stream tokenizer
      * recognizes C++-style comments. Any occurrence of two consecutive
-     * slash characters (<code>'/'</code>) is treated as the beginning of
+     * slash characters ({@code '/'}) is treated as the beginning of
      * a comment that extends to the end of the line.
      * <p>
-     * If the flag argument is <code>false</code>, then C++-style
+     * If the flag argument is {@code false}, then C++-style
      * comments are not treated specially.
      *
-     * @param   flag   <code>true</code> indicates to recognize and ignore
+     * @param   flag   {@code true} indicates to recognize and ignore
      *                 C++-style comments.
      */
     public void slashSlashComments(boolean flag) {
@@ -475,16 +475,16 @@
 
     /**
      * Determines whether or not word token are automatically lowercased.
-     * If the flag argument is <code>true</code>, then the value in the
-     * <code>sval</code> field is lowercased whenever a word token is
-     * returned (the <code>ttype</code> field has the
-     * value <code>TT_WORD</code> by the <code>nextToken</code> method
+     * If the flag argument is {@code true}, then the value in the
+     * {@code sval} field is lowercased whenever a word token is
+     * returned (the {@code ttype} field has the
+     * value {@code TT_WORD} by the {@code nextToken} method
      * of this tokenizer.
      * <p>
-     * If the flag argument is <code>false</code>, then the
-     * <code>sval</code> field is not modified.
+     * If the flag argument is {@code false}, then the
+     * {@code sval} field is not modified.
      *
-     * @param   fl   <code>true</code> indicates that all word tokens should
+     * @param   fl   {@code true} indicates that all word tokens should
      *               be lowercased.
      * @see     java.io.StreamTokenizer#nextToken()
      * @see     java.io.StreamTokenizer#ttype
@@ -506,9 +506,9 @@
 
     /**
      * Parses the next token from the input stream of this tokenizer.
-     * The type of the next token is returned in the <code>ttype</code>
+     * The type of the next token is returned in the {@code ttype}
      * field. Additional information about the token may be in the
-     * <code>nval</code> field or the <code>sval</code> field of this
+     * {@code nval} field or the {@code sval} field of this
      * tokenizer.
      * <p>
      * Typical clients of this
@@ -516,7 +516,7 @@
      * calling nextToken to parse successive tokens until TT_EOF
      * is returned.
      *
-     * @return     the value of the <code>ttype</code> field.
+     * @return     the value of the {@code ttype} field.
      * @exception  IOException  if an I/O error occurs.
      * @see        java.io.StreamTokenizer#nval
      * @see        java.io.StreamTokenizer#sval
@@ -752,10 +752,10 @@
     }
 
     /**
-     * Causes the next call to the <code>nextToken</code> method of this
-     * tokenizer to return the current value in the <code>ttype</code>
-     * field, and not to modify the value in the <code>nval</code> or
-     * <code>sval</code> field.
+     * Causes the next call to the {@code nextToken} method of this
+     * tokenizer to return the current value in the {@code ttype}
+     * field, and not to modify the value in the {@code nval} or
+     * {@code sval} field.
      *
      * @see     java.io.StreamTokenizer#nextToken()
      * @see     java.io.StreamTokenizer#nval
diff --git a/ojluni/src/main/java/java/io/StringReader.java b/ojluni/src/main/java/java/io/StringReader.java
index 3778408..ce9ff60 100644
--- a/ojluni/src/main/java/java/io/StringReader.java
+++ b/ojluni/src/main/java/java/io/StringReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -163,7 +163,7 @@
      *                         is no actual limit, so this argument must not
      *                         be negative, but is otherwise ignored.
      *
-     * @exception  IllegalArgumentException  If readAheadLimit is < 0
+     * @exception  IllegalArgumentException  If {@code readAheadLimit < 0}
      * @exception  IOException  If an I/O error occurs
      */
     public void mark(int readAheadLimit) throws IOException {
diff --git a/ojluni/src/main/java/java/io/UnixFileSystem.java b/ojluni/src/main/java/java/io/UnixFileSystem.java
index 6ce3f6f..1659b17 100644
--- a/ojluni/src/main/java/java/io/UnixFileSystem.java
+++ b/ojluni/src/main/java/java/io/UnixFileSystem.java
@@ -236,6 +236,7 @@
 
     private native int getBooleanAttributes0(String abspath);
 
+    // Android-changed: Added thread policy check
     public int getBooleanAttributes(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
 
@@ -245,43 +246,43 @@
         return rv | (hidden ? BA_HIDDEN : 0);
     }
 
+    // Android-changed: Added thread policy check
     public boolean checkAccess(File f, int access) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
         return checkAccess0(f, access);
     }
-
     private native boolean checkAccess0(File f, int access);
 
+    // Android-changed: Added thread policy check
     public long getLastModifiedTime(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
         return getLastModifiedTime0(f);
     }
-
     private native long getLastModifiedTime0(File f);
 
+    // Android-changed: Added thread policy check
     public long getLength(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
         return getLength0(f);
     }
-
     private native long getLength0(File f);
 
+    // Android-changed: Added thread policy check
     public boolean setPermission(File f, int access, boolean enable, boolean owneronly) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
         return setPermission0(f, access, enable, owneronly);
     }
-
     private native boolean setPermission0(File f, int access, boolean enable, boolean owneronly);
 
     /* -- File operations -- */
-
+    // Android-changed: Added thread policy check
     public boolean createFileExclusively(String path) throws IOException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
         return createFileExclusively0(path);
     }
-
     private native boolean createFileExclusively0(String path) throws IOException;
 
+    // Android-changed: Added thread policy check
     public boolean delete(File f) {
         // Keep canonicalization caches in sync after file deletion
         // and renaming operations. Could be more clever than this
@@ -296,20 +297,21 @@
 
     private native boolean delete0(File f);
 
+    // Android-changed: Added thread policy check
     public String[] list(File f) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
         return list0(f);
     }
-
     private native String[] list0(File f);
 
+    // Android-changed: Added thread policy check
     public boolean createDirectory(File f) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
         return createDirectory0(f);
     }
-
     private native boolean createDirectory0(File f);
 
+    // Android-changed: Added thread policy check
     public boolean rename(File f1, File f2) {
         // Keep canonicalization caches in sync after file deletion
         // and renaming operations. Could be more clever than this
@@ -324,18 +326,18 @@
 
     private native boolean rename0(File f1, File f2);
 
+    // Android-changed: Added thread policy check
     public boolean setLastModifiedTime(File f, long time) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
         return setLastModifiedTime0(f, time);
     }
-
     private native boolean setLastModifiedTime0(File f, long time);
 
+    // Android-changed: Added thread policy check
     public boolean setReadOnly(File f) {
         BlockGuard.getThreadPolicy().onWriteToDisk();
         return setReadOnly0(f);
     }
-
     private native boolean setReadOnly0(File f);
 
 
@@ -354,12 +356,12 @@
     }
 
     /* -- Disk usage -- */
+    // Android-changed: Added thread policy check
     public long getSpace(File f, int t) {
         BlockGuard.getThreadPolicy().onReadFromDisk();
 
         return getSpace0(f, t);
     }
-
     private native long getSpace0(File f, int t);
 
     /* -- Basic infrastructure -- */
diff --git a/ojluni/src/main/java/java/io/Writer.java b/ojluni/src/main/java/java/io/Writer.java
index f0c6db4..8747a13 100644
--- a/ojluni/src/main/java/java/io/Writer.java
+++ b/ojluni/src/main/java/java/io/Writer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,7 @@
     /**
      * Size of writeBuffer, must be >= 1
      */
-    private final int writeBufferSize = 1024;
+    private static final int WRITE_BUFFER_SIZE = 1024;
 
     /**
      * The object used to synchronize operations on this stream.  For
@@ -107,7 +107,7 @@
     public void write(int c) throws IOException {
         synchronized (lock) {
             if (writeBuffer == null){
-                writeBuffer = new char[writeBufferSize];
+                writeBuffer = new char[WRITE_BUFFER_SIZE];
             }
             writeBuffer[0] = (char) c;
             write(writeBuffer, 0, 1);
@@ -180,9 +180,9 @@
     public void write(String str, int off, int len) throws IOException {
         synchronized (lock) {
             char cbuf[];
-            if (len <= writeBufferSize) {
+            if (len <= WRITE_BUFFER_SIZE) {
                 if (writeBuffer == null) {
-                    writeBuffer = new char[writeBufferSize];
+                    writeBuffer = new char[WRITE_BUFFER_SIZE];
                 }
                 cbuf = writeBuffer;
             } else {    // Don't permanently allocate very large buffers.
diff --git a/ojluni/src/main/java/java/lang/Enum.java b/ojluni/src/main/java/java/lang/Enum.java
index 56666f2..8ada57f 100644
--- a/ojluni/src/main/java/java/lang/Enum.java
+++ b/ojluni/src/main/java/java/lang/Enum.java
@@ -234,26 +234,28 @@
      */
     public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                 String name) {
-        if (enumType == null)
+        // Android-changed: Use a static BasicLruCache mapping Enum class -> Enum instance array.
+        if (enumType == null) {
             throw new NullPointerException("enumType == null");
-        if (name == null)
-            throw new NullPointerException("Name is null");
+        }
+        if (name == null) {
+            throw new NullPointerException("name == null");
+        }
         T[] values = getSharedConstants(enumType);
-        T result = null;
-        if (values != null) {
-            for (T value : values) {
-                if (name.equals(value.name())) {
-                    result = value;
-                }
-            }
-        } else {
+        if (values == null) {
             throw new IllegalArgumentException(enumType.toString() + " is not an enum type.");
         }
 
-        if (result != null)
-            return result;
+        // Iterate backwards through the array to retain historic Android behavior in the
+        // unexpected / likely invalid case where there are multiple values with the same name.
+        for (int i = values.length - 1; i >= 0; --i) {
+            T value = values[i];
+            if (name.equals(value.name())) {
+                return value;
+            }
+        }
         throw new IllegalArgumentException(
-            "No enum constant " + enumType.getCanonicalName() + "." + name);
+                "No enum constant " + enumType.getCanonicalName() + "." + name);
     }
 
     private static final BasicLruCache<Class<? extends Enum>, Object[]> sharedConstantsCache
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
index ef4f7fe..0c27b99 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
@@ -455,16 +455,16 @@
      * field_id in the equivalent instruction.
      */
 
-    /** @hide */ public static final int INVOKE_VIRTUAL = 0x6e;
-    /** @hide */ public static final int INVOKE_SUPER = 0x6f;
-    /** @hide */ public static final int INVOKE_DIRECT = 0x70;
-    /** @hide */ public static final int INVOKE_STATIC = 0x71;
-    /** @hide */ public static final int INVOKE_INTERFACE = 0x72;
+    /** @hide */ public static final int INVOKE_VIRTUAL = 0;
+    /** @hide */ public static final int INVOKE_SUPER = 1;
+    /** @hide */ public static final int INVOKE_DIRECT = 2;
+    /** @hide */ public static final int INVOKE_STATIC = 3;
+    /** @hide */ public static final int INVOKE_INTERFACE = 4;
 
-    /** @hide */ public static final int SGET = 0x60;
-    /** @hide */ public static final int SPUT = 0x67;
-    /** @hide */ public static final int IGET = 0x52;
-    /** @hide */ public static final int IPUT = 0x59;
+    /** @hide */ public static final int SGET = 5;
+    /** @hide */ public static final int SPUT = 6;
+    /** @hide */ public static final int IGET = 7;
+    /** @hide */ public static final int IPUT = 8;
 
     // The kind of this method handle (used by the runtime). This is one of the INVOKE_*
     // constants or SGET/SPUT, IGET/IPUT.
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
index bd2f60d..a321410 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
@@ -1018,8 +1018,63 @@
          */
         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
-            // TODO(narayan): Implement this method.
-            throw new UnsupportedOperationException("MethodHandles.Lookup.findSpecial is not implemented");
+            if (specialCaller == null) {
+                throw new NullPointerException("specialCaller == null");
+            }
+
+            if (type == null) {
+                throw new NullPointerException("type == null");
+            }
+
+            if (name == null) {
+                throw new NullPointerException("name == null");
+            }
+
+            if (refc == null) {
+                throw new NullPointerException("ref == null");
+            }
+
+            // Make sure that the special caller is identical to the lookup class or that we have
+            // private access.
+            checkSpecialCaller(specialCaller);
+
+            // Even though constructors are invoked using a "special" invoke, handles to them can't
+            // be created using findSpecial. Callers must use findConstructor instead.
+            if ("<init>".equals(name)) {
+                throw new NoSuchMethodException("<init> is constructor.");
+            }
+
+            Method method = refc.getDeclaredMethod(name, type.ptypes());
+            if (Modifier.isPrivate(method.getModifiers())) {
+                // Since this is a private method, we'll need to also make sure that the
+                // lookup class is the same as the refering class. We've already checked that
+                // the specialCaller is the same as the special lookup class, both of these must
+                // be the same as the declaring class(*) in order to access the private method.
+                //
+                // (*) Well, this isn't true for nested classes but OpenJDK doesn't support those
+                // either.
+                if (refc != lookupClass()) {
+                    throw new IllegalAccessException("no private access for invokespecial : "
+                            + refc + ", from" + this);
+                }
+
+                // This is a private method, so there's nothing special to do.
+                MethodType handleType = type.insertParameterTypes(0, refc);
+                return new MethodHandleImpl(method.getArtMethod(), MethodHandle.INVOKE_DIRECT,
+                        handleType);
+            }
+
+            // This is a public, protected or package-private method, which means we're expecting
+            // invoke-super semantics. We'll have to restrict the receiver type appropriately on the
+            // handle once we check that there really is a "super" relationship between them.
+            if (!method.getDeclaringClass().isAssignableFrom(specialCaller)) {
+                throw new IllegalAccessException(refc + "is not assignable from " + specialCaller);
+            }
+
+            // Note that we restrict the receiver to "specialCaller" instances.
+            MethodType handleType = type.insertParameterTypes(0, specialCaller);
+            return new MethodHandleImpl(method.getArtMethod(), MethodHandle.INVOKE_SUPER,
+                    handleType);
         }
 
         /**
@@ -1404,17 +1459,21 @@
             return "member is private to package";
         }
 
-        private static final boolean ALLOW_NESTMATE_ACCESS = false;
+        // Android-changed: checkSpecialCaller assumes that ALLOW_NESTMATE_ACCESS = false,
+        // as in upstream OpenJDK.
+        //
+        // private static final boolean ALLOW_NESTMATE_ACCESS = false;
 
         private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
-            int allowedModes = this.allowedModes;
-            // Android-changed: No support for TRUSTED lookups.
+            // Android-changed: No support for TRUSTED lookups. Also construct the
+            // IllegalAccessException by hand because the upstream code implicitly assumes
+            // that the lookupClass == specialCaller.
+            //
             // if (allowedModes == TRUSTED)  return;
-            if (!hasPrivateAccess()
-                    || (specialCaller != lookupClass()
-                    && !(ALLOW_NESTMATE_ACCESS &&
-                    VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
-                throwMakeAccessException("no private access for invokespecial", this);
+            if (!hasPrivateAccess() || (specialCaller != lookupClass())) {
+                throw new IllegalAccessException("no private access for invokespecial : "
+                        + specialCaller + ", from" + this);
+            }
         }
 
         public void throwMakeAccessException(String message, Object from) throws
diff --git a/ojluni/src/main/java/java/net/Inet6AddressImpl.java b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
index 203ccb8..98417a9 100644
--- a/ojluni/src/main/java/java/net/Inet6AddressImpl.java
+++ b/ojluni/src/main/java/java/net/Inet6AddressImpl.java
@@ -28,13 +28,18 @@
 import android.system.GaiException;
 import android.system.StructAddrinfo;
 import dalvik.system.BlockGuard;
+
+import libcore.io.IoBridge;
 import libcore.io.Libcore;
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 
 import static android.system.OsConstants.AF_UNSPEC;
 import static android.system.OsConstants.AI_ADDRCONFIG;
 import static android.system.OsConstants.EACCES;
+import static android.system.OsConstants.ECONNREFUSED;
+import static android.system.OsConstants.NI_NAMEREQD;
 import static android.system.OsConstants.SOCK_STREAM;
 
 /*
@@ -140,9 +145,12 @@
 
     @Override
     public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif, int ttl) throws IOException {
-        byte[] ifaddr = null;
-        int scope = -1;
-        int netif_scope = -1;
+        // Android-changed: rewritten on the top of IoBridge and Libcore.os
+        // TODO (b/31926888): try ICMP first (http://code.google.com/p/android/issues/detail?id=20106)
+
+        // No good, let's fall back to TCP
+        FileDescriptor fd = IoBridge.socket(true);
+        InetAddress sourceAddr = null;
         if (netif != null) {
             /*
              * Let's make sure we bind to an address of the proper family.
@@ -155,31 +163,32 @@
             while (it.hasMoreElements()) {
                 inetaddr = it.nextElement();
                 if (inetaddr.getClass().isInstance(addr)) {
-                    ifaddr = inetaddr.getAddress();
-                    if (inetaddr instanceof Inet6Address) {
-                        netif_scope = ((Inet6Address) inetaddr).getScopeId();
-                    }
+                    sourceAddr = inetaddr;
                     break;
                 }
             }
-            if (ifaddr == null) {
+
+            if (sourceAddr == null) {
                 // Interface doesn't support the address family of
                 // the destination
                 return false;
             }
         }
-        if (addr instanceof Inet6Address)
-            scope = ((Inet6Address) addr).getScopeId();
 
-        BlockGuard.getThreadPolicy().onNetwork();
-
-        // Never throw an IOException from isReachable. If something terrible happens either
-        // with the network interface in question (or with the destination), then just return
-        // false (i.e, state that the address is unreachable.
         try {
-            return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope);
-        } catch (IOException ioe) {
-            return false;
+            if (sourceAddr != null) {
+                IoBridge.bind(fd, sourceAddr, 0);
+            }
+            IoBridge.connect(fd, addr, 7 /* Echo-protocol port */, timeout);
+            return true;
+        } catch (IOException e) {
+            // Connection refused by remote (ECONNREFUSED) implies reachable. Otherwise silently
+            // ignore the exception and return false.
+            Throwable cause = e.getCause();
+            return cause instanceof ErrnoException
+                    && ((ErrnoException) cause).errno == ECONNREFUSED;
+        } finally {
+            IoBridge.closeAndSignalBlockedThreads(fd);
         }
     }
 
@@ -215,6 +224,15 @@
         }
     }
 
-    private native String getHostByAddr0(byte[] addr) throws UnknownHostException;
-    private native boolean isReachable0(byte[] addr, int scope, int timeout, byte[] inf, int ttl, int if_scope) throws IOException;
+    private String getHostByAddr0(byte[] addr) throws UnknownHostException {
+        // Android-changed: Rewritten on the top of Libcore.os
+        InetAddress hostaddr = InetAddress.getByAddress(addr);
+        try {
+            return Libcore.os.getnameinfo(hostaddr, NI_NAMEREQD);
+        } catch (GaiException e) {
+            UnknownHostException uhe = new UnknownHostException(hostaddr.toString());
+            uhe.initCause(e);
+            throw uhe;
+        }
+    }
 }
diff --git a/ojluni/src/main/java/java/nio/file/FileSystem.java b/ojluni/src/main/java/java/nio/file/FileSystem.java
index 03ace89..bb6f136 100644
--- a/ojluni/src/main/java/java/nio/file/FileSystem.java
+++ b/ojluni/src/main/java/java/nio/file/FileSystem.java
@@ -335,18 +335,12 @@
      * </tr>
      * <tr>
      *   <td><tt>&#47;home&#47;*&#47;*</tt>
-     *   <td>Matches <tt>&#47;home&#47;gus&#47;data</tt> on UNIX platforms</td>
+     *   <td>Matches <tt>&#47;home&#47;gus&#47;data</tt></td>
      * </tr>
      * <tr>
      *   <td><tt>&#47;home&#47;**</tt>
      *   <td>Matches <tt>&#47;home&#47;gus</tt> and
-     *   <tt>&#47;home&#47;gus&#47;data</tt> on UNIX platforms</td>
-     * </tr>
-     * <tr>
-     *   <td><tt>C:&#92;&#92;*</tt>
-     *   <td>Matches <tt>C:&#92;foo</tt> and <tt>C:&#92;bar</tt> on the Windows
-     *   platform (note that the backslash is escaped; as a string literal in the
-     *   Java Language the pattern would be <tt>"C:&#92;&#92;&#92;&#92;*"</tt>) </td>
+     *   <tt>&#47;home&#47;gus&#47;data</tt></td>
      * </tr>
      *
      * </table>
diff --git a/ojluni/src/main/java/java/text/BreakIterator.java b/ojluni/src/main/java/java/text/BreakIterator.java
index be75a9e..6e7e053 100644
--- a/ojluni/src/main/java/java/text/BreakIterator.java
+++ b/ojluni/src/main/java/java/text/BreakIterator.java
@@ -445,6 +445,7 @@
      */
     public static BreakIterator getWordInstance(Locale locale)
     {
+        // Android-changed: Switched to ICU.
         return new IcuIteratorWrapper(
                 android.icu.text.BreakIterator.getWordInstance(locale));
     }
@@ -470,6 +471,7 @@
      */
     public static BreakIterator getLineInstance(Locale locale)
     {
+        // Android-changed: Switched to ICU.
         return new IcuIteratorWrapper(
                 android.icu.text.BreakIterator.getLineInstance(locale));
     }
@@ -495,6 +497,7 @@
      */
     public static BreakIterator getCharacterInstance(Locale locale)
     {
+        // Android-changed: Switched to ICU.
         return new IcuIteratorWrapper(
                 android.icu.text.BreakIterator.getCharacterInstance(locale));
     }
@@ -520,25 +523,23 @@
      */
     public static BreakIterator getSentenceInstance(Locale locale)
     {
+        // Android-changed: Switched to ICU.
         return new IcuIteratorWrapper(
                 android.icu.text.BreakIterator.getSentenceInstance(locale));
     }
 
+    // Android-changed: Removed references to BreakIteratorProvider.
     /**
      * Returns an array of all locales for which the
      * <code>get*Instance</code> methods of this class can return
      * localized instances.
-     * The returned array represents the union of locales supported by the Java
-     * runtime and by installed
-     * {@link java.text.spi.BreakIteratorProvider BreakIteratorProvider} implementations.
-     * It must contain at least a <code>Locale</code>
-     * instance equal to {@link java.util.Locale#US Locale.US}.
      *
      * @return An array of locales for which localized
      *         <code>BreakIterator</code> instances are available.
      */
     public static synchronized Locale[] getAvailableLocales()
     {
+        // Android-changed: Switched to ICU.
         return android.icu.text.BreakIterator.getAvailableLocales();
     }
 }
diff --git a/ojluni/src/main/java/java/text/Collator.java b/ojluni/src/main/java/java/text/Collator.java
index 478074c..01e7dc9 100644
--- a/ojluni/src/main/java/java/text/Collator.java
+++ b/ojluni/src/main/java/java/text/Collator.java
@@ -229,6 +229,7 @@
     public static synchronized
     Collator getInstance(Locale desiredLocale)
     {
+        // Android-changed: Switched to ICU.
         if (desiredLocale == null) {
             throw new NullPointerException("locale == null");
         }
@@ -317,6 +318,7 @@
      */
     public synchronized int getStrength()
     {
+        // Android-changed: Switched to ICU.
         // The value for IDENTICAL in ICU differs from that used in this class.
         int value = icuColl.getStrength();
         return (value == android.icu.text.Collator.IDENTICAL) ? IDENTICAL : value;
@@ -336,6 +338,7 @@
      * PRIMARY, SECONDARY, TERTIARY or IDENTICAL.
      */
     public synchronized void setStrength(int newStrength) {
+        // Android-changed: Switched to ICU.
         // The ICU value for IDENTICAL differs from that defined in this class.
         if (newStrength == IDENTICAL) {
             newStrength = android.icu.text.Collator.IDENTICAL;
@@ -364,6 +367,7 @@
      */
     public synchronized int getDecomposition()
     {
+        // Android-changed: Switched to ICU.
         return decompositionMode_ICU_Java(icuColl.getDecomposition());
     }
     /**
@@ -378,23 +382,21 @@
      * mode.
      */
     public synchronized void setDecomposition(int decompositionMode) {
+        // Android-changed: Switched to ICU.
         icuColl.setDecomposition(decompositionMode_Java_ICU(decompositionMode));
     }
 
+    // Android-changed: Removed references to CollatorProvider.
     /**
      * Returns an array of all locales for which the
      * <code>getInstance</code> methods of this class can return
      * localized instances.
-     * The returned array represents the union of locales supported
-     * by the Java runtime and by installed
-     * {@link java.text.spi.CollatorProvider CollatorProvider} implementations.
-     * It must contain at least a Locale instance equal to
-     * {@link java.util.Locale#US Locale.US}.
      *
      * @return An array of locales for which localized
      *         <code>Collator</code> instances are available.
      */
     public static synchronized Locale[] getAvailableLocales() {
+        // Android-changed: Removed reference to CollatorProvider. Switched to ICU.
         return ICU.getAvailableCollatorLocales();
     }
 
@@ -432,6 +434,7 @@
     public Object clone()
     {
         try {
+            // Android-changed: Switched to ICU.
             Collator clone = (Collator) super.clone();
             clone.icuColl = (android.icu.text.Collator) icuColl.clone();
             return clone;
@@ -459,6 +462,7 @@
             return false;
         }
         Collator other = (Collator) that;
+        // Android-changed: Switched to ICU.
         return icuColl == null ? other.icuColl == null : icuColl.equals(other.icuColl);
     }
 
@@ -476,6 +480,7 @@
      */
     protected Collator()
     {
+        // Android-changed: Switched to ICU.
         icuColl = android.icu.text.RuleBasedCollator.getInstance(Locale.getDefault());
     }
 
diff --git a/ojluni/src/main/java/java/text/DateFormat.java b/ojluni/src/main/java/java/text/DateFormat.java
index 6d7c956..799694e 100644
--- a/ojluni/src/main/java/java/text/DateFormat.java
+++ b/ojluni/src/main/java/java/text/DateFormat.java
@@ -40,18 +40,14 @@
 package java.text;
 
 import java.io.InvalidObjectException;
-import java.text.spi.DateFormatProvider;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 import java.util.MissingResourceException;
-import java.util.ResourceBundle;
 import java.util.TimeZone;
-import java.util.spi.LocaleServiceProvider;
-import sun.util.LocaleServiceProviderPool;
+import libcore.icu.ICU;
 
 /**
  * {@code DateFormat} is an abstract class for date/time formatting subclasses which
@@ -596,7 +592,12 @@
         return getDateTimeInstance(SHORT, SHORT);
     }
 
-    /** @hide */
+    // Android-changed: Added support for overriding locale default 12 / 24 hour preference.
+    /**
+     * {@code null}: use Locale default. {@code true}: force 24-hour format.
+     * {@code false} force 12-hour format.
+     * @hide
+     */
     public static Boolean is24Hour;
 
     /**
@@ -606,24 +607,19 @@
         DateFormat.is24Hour = is24Hour;
     }
 
+    // Android-changed: Remove reference to DateFormatProvider.
     /**
      * Returns an array of all locales for which the
      * <code>get*Instance</code> methods of this class can return
      * localized instances.
-     * The returned array represents the union of locales supported by the Java
-     * runtime and by installed
-     * {@link java.text.spi.DateFormatProvider DateFormatProvider} implementations.
-     * It must contain at least a <code>Locale</code> instance equal to
-     * {@link java.util.Locale#US Locale.US}.
      *
      * @return An array of locales for which localized
      *         <code>DateFormat</code> instances are available.
      */
     public static Locale[] getAvailableLocales()
     {
-        LocaleServiceProviderPool pool =
-            LocaleServiceProviderPool.getPool(DateFormatProvider.class);
-        return pool.getAvailableLocales();
+        // Android-changed: Removed used of DateFormatProvider. Switched to use ICU.
+        return ICU.getAvailableLocales();
     }
 
     /**
@@ -803,23 +799,8 @@
         } else {
             dateStyle = -1;
         }
+        // Android-changed: Removed used of DateFormatProvider.
         try {
-            // Check whether a provider can provide an implementation that's closer
-            // to the requested locale than what the Java runtime itself can provide.
-            LocaleServiceProviderPool pool =
-                LocaleServiceProviderPool.getPool(DateFormatProvider.class);
-            if (pool.hasProviders()) {
-                DateFormat providersInstance = pool.getLocalizedObject(
-                                                    DateFormatGetter.INSTANCE,
-                                                    loc,
-                                                    timeStyle,
-                                                    dateStyle,
-                                                    flags);
-                if (providersInstance != null) {
-                    return providersInstance;
-                }
-            }
-
             return new SimpleDateFormat(timeStyle, dateStyle, loc);
         } catch (MissingResourceException e) {
             return new SimpleDateFormat("M/d/yy h:mm a");
@@ -1046,37 +1027,4 @@
          */
         public final static Field TIME_ZONE = new Field("time zone", -1);
     }
-
-    /**
-     * Obtains a DateFormat instance from a DateFormatProvider
-     * implementation.
-     */
-    private static class DateFormatGetter
-        implements LocaleServiceProviderPool.LocalizedObjectGetter<DateFormatProvider, DateFormat> {
-        private static final DateFormatGetter INSTANCE = new DateFormatGetter();
-
-        public DateFormat getObject(DateFormatProvider dateFormatProvider,
-                                Locale locale,
-                                String key,
-                                Object... params) {
-            assert params.length == 3;
-
-            int timeStyle = (Integer)params[0];
-            int dateStyle = (Integer)params[1];
-            int flags = (Integer)params[2];
-
-            switch (flags) {
-            case 1:
-                return dateFormatProvider.getTimeInstance(timeStyle, locale);
-            case 2:
-                return dateFormatProvider.getDateInstance(dateStyle, locale);
-            case 3:
-                return dateFormatProvider.getDateTimeInstance(dateStyle, timeStyle, locale);
-            default:
-                assert false : "should not happen";
-            }
-
-            return null;
-        }
-    }
 }
diff --git a/ojluni/src/main/java/java/text/DateFormatSymbols.java b/ojluni/src/main/java/java/text/DateFormatSymbols.java
index c617a18..47f0973 100644
--- a/ojluni/src/main/java/java/text/DateFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DateFormatSymbols.java
@@ -44,7 +44,6 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.lang.ref.SoftReference;
-import java.text.spi.DateFormatSymbolsProvider;
 import java.util.Arrays;
 import java.util.Locale;
 import java.util.Objects;
@@ -52,9 +51,9 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import libcore.icu.ICU;
 import libcore.icu.LocaleData;
 import libcore.icu.TimeZoneNames;
-import sun.util.LocaleServiceProviderPool;
 
 /**
  * <code>DateFormatSymbols</code> is a public class for encapsulating
@@ -103,15 +102,13 @@
  */
 public class DateFormatSymbols implements Serializable, Cloneable {
 
+    // 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
      * resources for the default {@link java.util.Locale.Category#FORMAT FORMAT}
-     * locale. This constructor can only
-     * construct instances for the locales supported by the Java
-     * runtime environment, not for those supported by installed
-     * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
-     * implementations. For full locale coverage, use the
-     * {@link #getInstance(Locale) getInstance} method.
+     * locale. It is recommended that the {@link #getInstance(Locale) getInstance} method is used
+     * instead.
      * <p>This is equivalent to calling
      * {@link #DateFormatSymbols(Locale)
      *     DateFormatSymbols(Locale.getDefault(Locale.Category.FORMAT))}.
@@ -127,14 +124,12 @@
         initializeData(Locale.getDefault(Locale.Category.FORMAT));
     }
 
+    // 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
-     * resources for the given locale. This constructor can only
-     * construct instances for the locales supported by the Java
-     * runtime environment, not for those supported by installed
-     * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
-     * implementations. For full locale coverage, use the
-     * {@link #getInstance(Locale) getInstance} method.
+     * resources for the given locale. It is recommended that the
+     * {@link #getInstance(Locale) getInstance} method is used instead.
      *
      * @param locale the desired locale
      * @see #getInstance(Locale)
@@ -361,33 +356,25 @@
      */
     private String[] tinyStandAloneWeekdays;
 
+    // Android-changed: Removed reference to DateFormatSymbolsProvider.
     /**
      * Returns an array of all locales for which the
      * <code>getInstance</code> methods of this class can return
      * localized instances.
-     * The returned array represents the union of locales supported by the
-     * Java runtime and by installed
-     * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
-     * implementations.  It must contain at least a <code>Locale</code>
-     * instance equal to {@link java.util.Locale#US Locale.US}.
      *
      * @return An array of locales for which localized
      *         <code>DateFormatSymbols</code> instances are available.
      * @since 1.6
      */
     public static Locale[] getAvailableLocales() {
-        LocaleServiceProviderPool pool=
-            LocaleServiceProviderPool.getPool(DateFormatSymbolsProvider.class);
-        return pool.getAvailableLocales();
+        // Android-changed: No support for DateFormatSymbolsProvider.
+        return ICU.getAvailableLocales();
     }
 
+    // Android-changed: Removed reference to DateFormatSymbolsProvider.
     /**
      * Gets the <code>DateFormatSymbols</code> instance for the default
-     * locale.  This method provides access to <code>DateFormatSymbols</code>
-     * instances for locales supported by the Java runtime itself as well
-     * as for those supported by installed
-     * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
-     * implementations.
+     * locale.
      * <p>This is equivalent to calling {@link #getInstance(Locale)
      *     getInstance(Locale.getDefault(Locale.Category.FORMAT))}.
      * @see java.util.Locale#getDefault(java.util.Locale.Category)
@@ -399,23 +386,17 @@
         return getInstance(Locale.getDefault(Locale.Category.FORMAT));
     }
 
+    // Android-changed: Removed reference to DateFormatSymbolsProvider.
     /**
      * Gets the <code>DateFormatSymbols</code> instance for the specified
-     * locale.  This method provides access to <code>DateFormatSymbols</code>
-     * instances for locales supported by the Java runtime itself as well
-     * as for those supported by installed
-     * {@link java.text.spi.DateFormatSymbolsProvider DateFormatSymbolsProvider}
-     * implementations.
+     * locale.
      * @param locale the given locale.
      * @return a <code>DateFormatSymbols</code> instance.
      * @exception NullPointerException if <code>locale</code> is null
      * @since 1.6
      */
     public static final DateFormatSymbols getInstance(Locale locale) {
-        DateFormatSymbols dfs = getProviderInstance(locale);
-        if (dfs != null) {
-            return dfs;
-        }
+        // Android-changed: Removed used of DateFormatSymbolsProvider.
         return (DateFormatSymbols) getCachedInstance(locale).clone();
     }
 
@@ -426,27 +407,10 @@
      * an application.
      */
     static final DateFormatSymbols getInstanceRef(Locale locale) {
-        DateFormatSymbols dfs = getProviderInstance(locale);
-        if (dfs != null) {
-            return dfs;
-        }
+        // Android-changed: Removed used of DateFormatSymbolsProvider.
         return getCachedInstance(locale);
     }
 
-    private static DateFormatSymbols getProviderInstance(Locale locale) {
-        DateFormatSymbols providersInstance = null;
-
-        // Check whether a provider can provide an implementation that's closer
-        // to the requested locale than what the Java runtime itself can provide.
-        LocaleServiceProviderPool pool =
-            LocaleServiceProviderPool.getPool(DateFormatSymbolsProvider.class);
-        if (pool.hasProviders()) {
-            providersInstance = pool.getLocalizedObject(
-                                    DateFormatSymbolsGetter.INSTANCE, locale);
-        }
-        return providersInstance;
-    }
-
     /**
      * Returns a cached DateFormatSymbols if it's found in the
      * cache. Otherwise, this method returns a newly cached instance
@@ -580,6 +544,7 @@
         cachedHashCode = 0;
     }
 
+    // Android-changed: Removed reference to TimeZoneNameProvider.
     /**
      * Gets time zone strings.  Use of this method is discouraged; use
      * {@link java.util.TimeZone#getDisplayName() TimeZone.getDisplayName()}
@@ -611,9 +576,7 @@
      * If {@link #setZoneStrings(String[][]) setZoneStrings} has been called
      * on this <code>DateFormatSymbols</code> instance, then the strings
      * provided by that call are returned. Otherwise, the returned array
-     * contains names provided by the Java runtime and by installed
-     * {@link java.util.spi.TimeZoneNameProvider TimeZoneNameProvider}
-     * implementations.
+     * contains names provided by the runtime.
      *
      * @return the time zone strings.
      * @see #setZoneStrings(String[][])
@@ -1004,23 +967,4 @@
         internalZoneStrings();
         stream.defaultWriteObject();
     }
-
-    /**
-     * Obtains a DateFormatSymbols instance from a DateFormatSymbolsProvider
-     * implementation.
-     */
-    private static class DateFormatSymbolsGetter
-        implements LocaleServiceProviderPool.LocalizedObjectGetter<DateFormatSymbolsProvider,
-                                                                   DateFormatSymbols> {
-        private static final DateFormatSymbolsGetter INSTANCE =
-            new DateFormatSymbolsGetter();
-
-        public DateFormatSymbols getObject(DateFormatSymbolsProvider dateFormatSymbolsProvider,
-                                Locale locale,
-                                String key,
-                                Object... params) {
-            assert params.length == 0;
-            return dateFormatSymbolsProvider.getInstance(locale);
-        }
-    }
 }
diff --git a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
index a2bb05b..3937065 100644
--- a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
@@ -44,14 +44,12 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.text.spi.DecimalFormatSymbolsProvider;
 import java.util.Currency;
 import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
+import libcore.icu.ICU;
 import libcore.icu.LocaleData;
 
-import sun.util.LocaleServiceProviderPool;
-
 /**
  * This class represents the set of symbols (such as the decimal separator,
  * the grouping separator, and so on) needed by <code>DecimalFormat</code>
@@ -68,15 +66,13 @@
 
 public class DecimalFormatSymbols implements Cloneable, Serializable {
 
+    // Android-changed: Removed reference to DecimalFormatSymbolsProvider but suggested
+    // getInstance() be used instead in case Android supports it in future.
     /**
      * Create a DecimalFormatSymbols object for the default
      * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
-     * This constructor can only construct instances for the locales
-     * supported by the Java runtime environment, not for those
-     * supported by installed
-     * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
-     * implementations. For full locale coverage, use the
-     * {@link #getInstance(Locale) getInstance} method.
+     * It is recommended that the {@link #getInstance(Locale) getInstance} method is used
+     * instead.
      * <p>This is equivalent to calling
      * {@link #DecimalFormatSymbols(Locale)
      *     DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT))}.
@@ -87,14 +83,12 @@
         initialize( Locale.getDefault(Locale.Category.FORMAT) );
     }
 
+    // Android-changed: Removed reference to DecimalFormatSymbolsProvider but suggested
+    // getInstance() be used instead in case Android supports it in future.
     /**
      * Create a DecimalFormatSymbols object for the given locale.
-     * This constructor can only construct instances for the locales
-     * supported by the Java runtime environment, not for those
-     * supported by installed
-     * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
-     * implementations. For full locale coverage, use the
-     * {@link #getInstance(Locale) getInstance} method.
+     * It is recommended that the {@link #getInstance(Locale) getInstance} method is used
+     * instead.
      * If the specified locale contains the {@link java.util.Locale#UNICODE_LOCALE_EXTENSION}
      * for the numbering system, the instance is initialized with the specified numbering
      * system if the JRE implementation supports it. For example,
@@ -111,33 +105,25 @@
         initialize( locale );
     }
 
+    // Android-changed: Removed reference to DecimalFormatSymbolsProvider.
     /**
      * Returns an array of all locales for which the
      * <code>getInstance</code> methods of this class can return
      * localized instances.
-     * The returned array represents the union of locales supported by the Java
-     * runtime and by installed
-     * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
-     * implementations.  It must contain at least a <code>Locale</code>
-     * instance equal to {@link java.util.Locale#US Locale.US}.
      *
      * @return an array of locales for which localized
      *         <code>DecimalFormatSymbols</code> instances are available.
      * @since 1.6
      */
     public static Locale[] getAvailableLocales() {
-        LocaleServiceProviderPool pool =
-            LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
-        return pool.getAvailableLocales();
+        // Android-changed: Removed used of DecimalFormatSymbolsProvider. Switched to use ICU.
+        return ICU.getAvailableLocales();
     }
 
+    // Android-changed: Removed reference to DecimalFormatSymbolsProvider.
     /**
      * Gets the <code>DecimalFormatSymbols</code> instance for the default
-     * locale.  This method provides access to <code>DecimalFormatSymbols</code>
-     * instances for locales supported by the Java runtime itself as well
-     * as for those supported by installed
-     * {@link java.text.spi.DecimalFormatSymbolsProvider
-     * DecimalFormatSymbolsProvider} implementations.
+     * locale.
      * <p>This is equivalent to calling
      * {@link #getInstance(Locale)
      *     getInstance(Locale.getDefault(Locale.Category.FORMAT))}.
@@ -150,13 +136,10 @@
         return getInstance(Locale.getDefault(Locale.Category.FORMAT));
     }
 
+    // Android-changed: Removed reference to DecimalFormatSymbolsProvider.
     /**
      * Gets the <code>DecimalFormatSymbols</code> instance for the specified
-     * locale.  This method provides access to <code>DecimalFormatSymbols</code>
-     * instances for locales supported by the Java runtime itself as well
-     * as for those supported by installed
-     * {@link java.text.spi.DecimalFormatSymbolsProvider
-     * DecimalFormatSymbolsProvider} implementations.
+     * locale.
      * If the specified locale contains the {@link java.util.Locale#UNICODE_LOCALE_EXTENSION}
      * for the numbering system, the instance is initialized with the specified numbering
      * system if the JRE implementation supports it. For example,
@@ -172,19 +155,7 @@
      * @since 1.6
      */
     public static final DecimalFormatSymbols getInstance(Locale locale) {
-
-        // Check whether a provider can provide an implementation that's closer
-        // to the requested locale than what the Java runtime itself can provide.
-        LocaleServiceProviderPool pool =
-            LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
-        if (pool.hasProviders()) {
-            DecimalFormatSymbols providersInstance = pool.getLocalizedObject(
-                                DecimalFormatSymbolsGetter.INSTANCE, locale);
-            if (providersInstance != null) {
-                return providersInstance;
-            }
-        }
-
+        // Android-changed: Removed used of DecimalFormatSymbolsProvider.
         return new DecimalFormatSymbols(locale);
     }
 
@@ -659,6 +630,7 @@
     private void initialize( Locale locale ) {
         this.locale = locale;
 
+        // Android-changed: Removed use of DecimalFormatSymbolsProvider. Switched to ICU.
         // get resource bundle data - try the cache first
         boolean needCacheUpdate = false;
         Object[] data = cachedLocaleData.get(locale);
@@ -1128,24 +1100,4 @@
     private static final ConcurrentHashMap<Locale, Object[]> cachedLocaleData = new ConcurrentHashMap<Locale, Object[]>(3);
 
     private transient android.icu.text.DecimalFormatSymbols cachedIcuDFS = null;
-
-    /**
-     * Obtains a DecimalFormatSymbols instance from a DecimalFormatSymbolsProvider
-     * implementation.
-     */
-    private static class DecimalFormatSymbolsGetter
-        implements LocaleServiceProviderPool.LocalizedObjectGetter<DecimalFormatSymbolsProvider,
-                                                                   DecimalFormatSymbols> {
-        private static final DecimalFormatSymbolsGetter INSTANCE =
-            new DecimalFormatSymbolsGetter();
-
-        public DecimalFormatSymbols getObject(
-                                DecimalFormatSymbolsProvider decimalFormatSymbolsProvider,
-                                Locale locale,
-                                String key,
-                                Object... params) {
-            assert params.length == 0;
-            return decimalFormatSymbolsProvider.getInstance(locale);
-        }
-    }
 }
diff --git a/ojluni/src/main/java/java/text/NumberFormat.java b/ojluni/src/main/java/java/text/NumberFormat.java
index 476983f..218a668 100644
--- a/ojluni/src/main/java/java/text/NumberFormat.java
+++ b/ojluni/src/main/java/java/text/NumberFormat.java
@@ -45,18 +45,15 @@
 import java.io.ObjectOutputStream;
 import java.math.BigInteger;
 import java.math.RoundingMode;
-import java.text.spi.NumberFormatProvider;
 import java.util.Currency;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Map;
-import java.util.ResourceBundle;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
-import java.util.spi.LocaleServiceProvider;
+import libcore.icu.ICU;
 import libcore.icu.LocaleData;
-import sun.util.LocaleServiceProviderPool;
 
 /**
  * <code>NumberFormat</code> is the abstract base class for all number
@@ -548,23 +545,18 @@
         return getInstance(inLocale, PERCENTSTYLE);
     }
 
+    // Android-changed: Removed reference to NumberFormatProvider.
     /**
      * Returns an array of all locales for which the
      * <code>get*Instance</code> methods of this class can return
      * localized instances.
-     * The returned array represents the union of locales supported by the Java
-     * runtime and by installed
-     * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
-     * It must contain at least a <code>Locale</code> instance equal to
-     * {@link java.util.Locale#US Locale.US}.
      *
      * @return An array of locales for which localized
      *         <code>NumberFormat</code> instances are available.
      */
     public static Locale[] getAvailableLocales() {
-        LocaleServiceProviderPool pool =
-            LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
-        return pool.getAvailableLocales();
+        // Android-changed: Removed used of NumberFormatProvider. Switched to use ICU.
+        return ICU.getAvailableLocales();
     }
 
     /**
@@ -829,20 +821,7 @@
 
     private static NumberFormat getInstance(Locale desiredLocale,
                                            int choice) {
-        // Check whether a provider can provide an implementation that's closer
-        // to the requested locale than what the Java runtime itself can provide.
-        LocaleServiceProviderPool pool =
-            LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
-        if (pool.hasProviders()) {
-            NumberFormat providersInstance = pool.getLocalizedObject(
-                                    NumberFormatGetter.INSTANCE,
-                                    desiredLocale,
-                                    choice);
-            if (providersInstance != null) {
-                return providersInstance;
-            }
-        }
-
+        // Android-changed: Removed use of NumberFormatProvider. Switched to use ICU.
         /* try the cache first */
         String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
         if (numberPatterns == null) { /* cache miss */
@@ -1219,36 +1198,4 @@
          */
         public static final Field EXPONENT_SIGN = new Field("exponent sign");
     }
-
-    /**
-     * Obtains a NumberFormat instance from a NumberFormatProvider implementation.
-     */
-    private static class NumberFormatGetter
-        implements LocaleServiceProviderPool.LocalizedObjectGetter<NumberFormatProvider,
-                                                                   NumberFormat> {
-        private static final NumberFormatGetter INSTANCE = new NumberFormatGetter();
-
-        public NumberFormat getObject(NumberFormatProvider numberFormatProvider,
-                                Locale locale,
-                                String key,
-                                Object... params) {
-            assert params.length == 1;
-            int choice = (Integer)params[0];
-
-            switch (choice) {
-            case NUMBERSTYLE:
-                return numberFormatProvider.getNumberInstance(locale);
-            case PERCENTSTYLE:
-                return numberFormatProvider.getPercentInstance(locale);
-            case CURRENCYSTYLE:
-                return numberFormatProvider.getCurrencyInstance(locale);
-            case INTEGERSTYLE:
-                return numberFormatProvider.getIntegerInstance(locale);
-            default:
-                assert false : choice;
-            }
-
-            return null;
-        }
-    }
 }
diff --git a/ojluni/src/main/java/java/text/SimpleDateFormat.java b/ojluni/src/main/java/java/text/SimpleDateFormat.java
index b17245f..de2a93e 100644
--- a/ojluni/src/main/java/java/text/SimpleDateFormat.java
+++ b/ojluni/src/main/java/java/text/SimpleDateFormat.java
@@ -534,12 +534,6 @@
     private static final String GMT = "GMT";
 
     /**
-     * Cache to hold the DateTimePatterns of a Locale.
-     */
-    private static final ConcurrentMap<Locale, String[]> cachedLocaleData
-        = new ConcurrentHashMap<Locale, String[]>(3);
-
-    /**
      * Cache NumberFormat instances with Locale key.
      */
     private static final ConcurrentMap<Locale, NumberFormat> cachedNumberFormatData
@@ -662,33 +656,20 @@
         // initialize calendar and related fields
         initializeCalendar(loc);
 
-        /* try the cache first */
-        String[] dateTimePatterns = cachedLocaleData.get(loc);
-        if (dateTimePatterns == null) { /* cache miss */
-            LocaleData localeData = LocaleData.get(loc);
-            dateTimePatterns = new String[9];
-            dateTimePatterns[DateFormat.SHORT + 4] = localeData.getDateFormat(DateFormat.SHORT);
-            dateTimePatterns[DateFormat.MEDIUM + 4] = localeData.getDateFormat(DateFormat.MEDIUM);
-            dateTimePatterns[DateFormat.LONG + 4] = localeData.getDateFormat(DateFormat.LONG);
-            dateTimePatterns[DateFormat.FULL + 4] = localeData.getDateFormat(DateFormat.FULL);
-            dateTimePatterns[DateFormat.SHORT] = localeData.getTimeFormat(DateFormat.SHORT);
-            dateTimePatterns[DateFormat.MEDIUM] = localeData.getTimeFormat(DateFormat.MEDIUM);
-            dateTimePatterns[DateFormat.LONG] = localeData.getTimeFormat(DateFormat.LONG);
-            dateTimePatterns[DateFormat.FULL] = localeData.getTimeFormat(DateFormat.FULL);
-            dateTimePatterns[8] = "{0} {1}";
-            /* update cache */
-            cachedLocaleData.putIfAbsent(loc, dateTimePatterns);
-        }
         formatData = DateFormatSymbols.getInstanceRef(loc);
+        LocaleData localeData = LocaleData.get(loc);
         if ((timeStyle >= 0) && (dateStyle >= 0)) {
-            Object[] dateTimeArgs = {dateTimePatterns[dateStyle + 4], dateTimePatterns[timeStyle]};
-            pattern = MessageFormat.format(dateTimePatterns[8], dateTimeArgs);
+            Object[] dateTimeArgs = {
+                localeData.getDateFormat(dateStyle),
+                localeData.getTimeFormat(timeStyle),
+            };
+            pattern = MessageFormat.format("{0} {1}", dateTimeArgs);
         }
         else if (timeStyle >= 0) {
-            pattern = dateTimePatterns[timeStyle];
+            pattern = localeData.getTimeFormat(timeStyle);
         }
         else if (dateStyle >= 0) {
-            pattern = dateTimePatterns[dateStyle + 4];
+            pattern = localeData.getDateFormat(dateStyle);
         }
         else {
             throw new IllegalArgumentException("No date or time style specified");
diff --git a/ojluni/src/main/java/java/text/spi/BreakIteratorProvider.java b/ojluni/src/main/java/java/text/spi/BreakIteratorProvider.java
deleted file mode 100644
index dd4a1a2..0000000
--- a/ojluni/src/main/java/java/text/spi/BreakIteratorProvider.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.text.spi;
-
-import java.text.BreakIterator;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * An abstract class for service providers that
- * provide concrete implementations of the
- * {@link java.text.BreakIterator BreakIterator} class.
- *
- * @since        1.6
- */
-public abstract class BreakIteratorProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected BreakIteratorProvider() {
-    }
-
-    /**
-     * Returns a new <code>BreakIterator</code> instance
-     * for <a href="../BreakIterator.html#word">word breaks</a>
-     * for the given locale.
-     * @param locale the desired locale
-     * @return A break iterator for word breaks
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.text.BreakIterator#getWordInstance(java.util.Locale)
-     */
-    public abstract BreakIterator getWordInstance(Locale locale);
-
-    /**
-     * Returns a new <code>BreakIterator</code> instance
-     * for <a href="../BreakIterator.html#line">line breaks</a>
-     * for the given locale.
-     * @param locale the desired locale
-     * @return A break iterator for line breaks
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.text.BreakIterator#getLineInstance(java.util.Locale)
-     */
-    public abstract BreakIterator getLineInstance(Locale locale);
-
-    /**
-     * Returns a new <code>BreakIterator</code> instance
-     * for <a href="../BreakIterator.html#character">character breaks</a>
-     * for the given locale.
-     * @param locale the desired locale
-     * @return A break iterator for character breaks
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.text.BreakIterator#getCharacterInstance(java.util.Locale)
-     */
-    public abstract BreakIterator getCharacterInstance(Locale locale);
-
-    /**
-     * Returns a new <code>BreakIterator</code> instance
-     * for <a href="../BreakIterator.html#sentence">sentence breaks</a>
-     * for the given locale.
-     * @param locale the desired locale
-     * @return A break iterator for sentence breaks
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.text.BreakIterator#getSentenceInstance(java.util.Locale)
-     */
-    public abstract BreakIterator getSentenceInstance(Locale locale);
-}
diff --git a/ojluni/src/main/java/java/text/spi/CollatorProvider.java b/ojluni/src/main/java/java/text/spi/CollatorProvider.java
deleted file mode 100644
index 1480908..0000000
--- a/ojluni/src/main/java/java/text/spi/CollatorProvider.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.text.spi;
-
-import java.text.Collator;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * An abstract class for service providers that
- * provide concrete implementations of the
- * {@link java.text.Collator Collator} class.
- *
- * @since        1.6
- */
-public abstract class CollatorProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected CollatorProvider() {
-    }
-
-    /**
-     * Returns a new <code>Collator</code> instance for the specified locale.
-     * @param locale the desired locale.
-     * @return the <code>Collator</code> for the desired locale.
-     * @exception NullPointerException if
-     * <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.text.Collator#getInstance(java.util.Locale)
-     */
-    public abstract Collator getInstance(Locale locale);
-}
diff --git a/ojluni/src/main/java/java/text/spi/DateFormatProvider.java b/ojluni/src/main/java/java/text/spi/DateFormatProvider.java
deleted file mode 100644
index e12effd..0000000
--- a/ojluni/src/main/java/java/text/spi/DateFormatProvider.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.text.spi;
-
-import java.text.DateFormat;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * An abstract class for service providers that
- * provide concrete implementations of the
- * {@link java.text.DateFormat DateFormat} class.
- *
- * @since        1.6
- */
-public abstract class DateFormatProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected DateFormatProvider() {
-    }
-
-    /**
-     * Returns a new <code>DateFormat</code> instance which formats time
-     * with the given formatting style for the specified locale.
-     * @param style the given formatting style.  Either one of
-     *     {@link java.text.DateFormat#SHORT DateFormat.SHORT},
-     *     {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM},
-     *     {@link java.text.DateFormat#LONG DateFormat.LONG}, or
-     *     {@link java.text.DateFormat#FULL DateFormat.FULL}.
-     * @param locale the desired locale.
-     * @exception IllegalArgumentException if <code>style</code> is invalid,
-     *     or if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @exception NullPointerException if <code>locale</code> is null
-     * @return a time formatter.
-     * @see java.text.DateFormat#getTimeInstance(int, java.util.Locale)
-     */
-    public abstract DateFormat getTimeInstance(int style, Locale locale);
-
-    /**
-     * Returns a new <code>DateFormat</code> instance which formats date
-     * with the given formatting style for the specified locale.
-     * @param style the given formatting style.  Either one of
-     *     {@link java.text.DateFormat#SHORT DateFormat.SHORT},
-     *     {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM},
-     *     {@link java.text.DateFormat#LONG DateFormat.LONG}, or
-     *     {@link java.text.DateFormat#FULL DateFormat.FULL}.
-     * @param locale the desired locale.
-     * @exception IllegalArgumentException if <code>style</code> is invalid,
-     *     or if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @exception NullPointerException if <code>locale</code> is null
-     * @return a date formatter.
-     * @see java.text.DateFormat#getDateInstance(int, java.util.Locale)
-     */
-    public abstract DateFormat getDateInstance(int style, Locale locale);
-
-    /**
-     * Returns a new <code>DateFormat</code> instance which formats date and time
-     * with the given formatting style for the specified locale.
-     * @param dateStyle the given date formatting style.  Either one of
-     *     {@link java.text.DateFormat#SHORT DateFormat.SHORT},
-     *     {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM},
-     *     {@link java.text.DateFormat#LONG DateFormat.LONG}, or
-     *     {@link java.text.DateFormat#FULL DateFormat.FULL}.
-     * @param timeStyle the given time formatting style.  Either one of
-     *     {@link java.text.DateFormat#SHORT DateFormat.SHORT},
-     *     {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM},
-     *     {@link java.text.DateFormat#LONG DateFormat.LONG}, or
-     *     {@link java.text.DateFormat#FULL DateFormat.FULL}.
-     * @param locale the desired locale.
-     * @exception IllegalArgumentException if <code>dateStyle</code> or
-     *     <code>timeStyle</code> is invalid,
-     *     or if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @exception NullPointerException if <code>locale</code> is null
-     * @return a date/time formatter.
-     * @see java.text.DateFormat#getDateTimeInstance(int, int, java.util.Locale)
-     */
-    public abstract DateFormat
-        getDateTimeInstance(int dateStyle, int timeStyle, Locale locale);
-}
diff --git a/ojluni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java b/ojluni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java
deleted file mode 100644
index bc3a8fb..0000000
--- a/ojluni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.text.spi;
-
-import java.text.DateFormatSymbols;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * An abstract class for service providers that
- * provide instances of the
- * {@link java.text.DateFormatSymbols DateFormatSymbols} class.
- *
- * @since        1.6
- */
-public abstract class DateFormatSymbolsProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected DateFormatSymbolsProvider() {
-    }
-
-    /**
-     * Returns a new <code>DateFormatSymbols</code> instance for the
-     * specified locale.
-     *
-     * @param locale the desired locale
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @return a <code>DateFormatSymbols</code> instance.
-     * @see java.text.DateFormatSymbols#getInstance(java.util.Locale)
-     */
-    public abstract DateFormatSymbols getInstance(Locale locale);
-}
diff --git a/ojluni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java b/ojluni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java
deleted file mode 100644
index d1d078c..0000000
--- a/ojluni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.text.spi;
-
-import java.text.DecimalFormatSymbols;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * An abstract class for service providers that
- * provide instances of the
- * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} class.
- *
- * <p>The requested {@code Locale} may contain an <a
- * href="../../util/Locale.html#def_locale_extension"> extension</a> for
- * specifying the desired numbering system. For example, {@code "ar-u-nu-arab"}
- * (in the BCP 47 language tag form) specifies Arabic with the Arabic-Indic
- * digits and symbols, while {@code "ar-u-nu-latn"} specifies Arabic with the
- * Latin digits and symbols. Refer to the <em>Unicode Locale Data Markup
- * Language (LDML)</em> specification for numbering systems.
- *
- * @since        1.6
- * @see Locale#forLanguageTag(String)
- * @see Locale#getExtension(char)
- */
-public abstract class DecimalFormatSymbolsProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected DecimalFormatSymbolsProvider() {
-    }
-
-    /**
-     * Returns a new <code>DecimalFormatSymbols</code> instance for the
-     * specified locale.
-     *
-     * @param locale the desired locale
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @return a <code>DecimalFormatSymbols</code> instance.
-     * @see java.text.DecimalFormatSymbols#getInstance(java.util.Locale)
-     */
-    public abstract DecimalFormatSymbols getInstance(Locale locale);
-}
diff --git a/ojluni/src/main/java/java/text/spi/NumberFormatProvider.java b/ojluni/src/main/java/java/text/spi/NumberFormatProvider.java
deleted file mode 100644
index a375b69..0000000
--- a/ojluni/src/main/java/java/text/spi/NumberFormatProvider.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.text.spi;
-
-import java.text.NumberFormat;
-import java.util.Locale;
-import java.util.spi.LocaleServiceProvider;
-
-/**
- * An abstract class for service providers that
- * provide concrete implementations of the
- * {@link java.text.NumberFormat NumberFormat} class.
- *
- * @since        1.6
- */
-public abstract class NumberFormatProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected NumberFormatProvider() {
-    }
-
-    /**
-     * Returns a new <code>NumberFormat</code> instance which formats
-     * monetary values for the specified locale.
-     *
-     * @param locale the desired locale.
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @return a currency formatter
-     * @see java.text.NumberFormat#getCurrencyInstance(java.util.Locale)
-     */
-    public abstract NumberFormat getCurrencyInstance(Locale locale);
-
-    /**
-     * Returns a new <code>NumberFormat</code> instance which formats
-     * integer values for the specified locale.
-     * The returned number format is configured to
-     * round floating point numbers to the nearest integer using
-     * half-even rounding (see {@link java.math.RoundingMode#HALF_EVEN HALF_EVEN})
-     * for formatting, and to parse only the integer part of
-     * an input string (see {@link
-     * java.text.NumberFormat#isParseIntegerOnly isParseIntegerOnly}).
-     *
-     * @param locale the desired locale
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @return a number format for integer values
-     * @see java.text.NumberFormat#getIntegerInstance(java.util.Locale)
-     */
-    public abstract NumberFormat getIntegerInstance(Locale locale);
-
-    /**
-     * Returns a new general-purpose <code>NumberFormat</code> instance for
-     * the specified locale.
-     *
-     * @param locale the desired locale
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @return a general-purpose number formatter
-     * @see java.text.NumberFormat#getNumberInstance(java.util.Locale)
-     */
-    public abstract NumberFormat getNumberInstance(Locale locale);
-
-    /**
-     * Returns a new <code>NumberFormat</code> instance which formats
-     * percentage values for the specified locale.
-     *
-     * @param locale the desired locale
-     * @exception NullPointerException if <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @return a percent formatter
-     * @see java.text.NumberFormat#getPercentInstance(java.util.Locale)
-     */
-    public abstract NumberFormat getPercentInstance(Locale locale);
-}
diff --git a/ojluni/src/main/java/java/text/spi/package.html b/ojluni/src/main/java/java/text/spi/package.html
deleted file mode 100644
index fa08ec1..0000000
--- a/ojluni/src/main/java/java/text/spi/package.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 2 only, as
-published by the Free Software Foundation.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the LICENSE file that accompanied this code.
-
-This code is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-version 2 for more details (a copy is included in the LICENSE file that
-accompanied this code).
-
-You should have received a copy of the GNU General Public License version
-2 along with this work; if not, write to the Free Software Foundation,
-Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-or visit www.oracle.com if you need additional information or have any
-questions.
--->
-
-</head>
-<body bgcolor="white">
-Service provider classes for the classes in the java.text package.
-<!--
-<h2>Package Specification</h2>
-
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
-<ul>
-  <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
-</ul>
-
-<h2>Related Documentation</h2>
-
-For overviews, tutorials, examples, guides, and tool documentation, please see:
-<ul>
-  <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
-</ul>
--->
-
-@since 1.6
-</body>
-</html>
diff --git a/ojluni/src/main/java/java/util/Arrays.java b/ojluni/src/main/java/java/util/Arrays.java
index df3f769..0f175c3 100644
--- a/ojluni/src/main/java/java/util/Arrays.java
+++ b/ojluni/src/main/java/java/util/Arrays.java
@@ -26,7 +26,7 @@
 
 package java.util;
 
-import java.lang.reflect.*;
+import java.lang.reflect.Array;
 import java.util.concurrent.ForkJoinPool;
 import java.util.function.BinaryOperator;
 import java.util.function.Consumer;
@@ -80,6 +80,8 @@
      */
     public static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
 
+    // Suppresses default constructor, ensuring non-instantiability.
+    private Arrays() {}
 
     /**
      * A comparator that implements the natural ordering of a group of
@@ -104,11 +106,43 @@
         static final NaturalOrder INSTANCE = new NaturalOrder();
     }
 
-    // Suppresses default constructor, ensuring non-instantiability.
-    private Arrays() {}
+    /**
+     * Checks that {@code fromIndex} and {@code toIndex} are in
+     * the range and throws an appropriate exception, if they aren't.
+     */
+    private static void rangeCheck(int length, int fromIndex, int toIndex) {
+        if (fromIndex > toIndex) {
+            throw new IllegalArgumentException(
+                "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
+        }
+        if (fromIndex < 0) {
+            throw new ArrayIndexOutOfBoundsException(fromIndex);
+        }
+        if (toIndex > length) {
+            throw new ArrayIndexOutOfBoundsException(toIndex);
+        }
+    }
+
+    /**
+     * Checks that the range described by {@code offset} and {@code count} doesn't exceed
+     * {@code arrayLength}.
+     *
+     * Android changed.
+     * @hide
+     */
+    public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
+        if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
+            throw new ArrayIndexOutOfBoundsException(arrayLength, offset,
+                    count);
+        }
+    }
 
     /*
-     * Sorting of primitive type arrays.
+     * Sorting methods. Note that all public "sort" methods take the
+     * same form: Performing argument checks if necessary, and then
+     * expanding arguments into those required for the internal
+     * implementation methods residing in other package-private
+     * classes (except for legacyMergeSort, included in this class).
      */
 
     /**
@@ -1167,50 +1201,6 @@
      */
 
     /**
-     * Old merge sort implementation can be selected (for
-     * compatibility with broken comparators) using a system property.
-     * Cannot be a static boolean in the enclosing class due to
-     * circular dependencies. To be removed in a future release.
-     */
-    static final class LegacyMergeSort {
-        // Android-changed: Never use circular merge sort.
-        private static final boolean userRequested = false;
-    }
-
-    /*
-     * If this platform has an optimizing VM, check whether ComparableTimSort
-     * offers any performance benefit over TimSort in conjunction with a
-     * comparator that returns:
-     *    {@code ((Comparable)first).compareTo(Second)}.
-     * If not, you are better off deleting ComparableTimSort to
-     * eliminate the code duplication.  In other words, the commented
-     * out code below is the preferable implementation for sorting
-     * arrays of Comparables if it offers sufficient performance.
-     */
-
-//    /**
-//     * A comparator that implements the natural ordering of a group of
-//     * mutually comparable elements.  Using this comparator saves us
-//     * from duplicating most of the code in this file (one version for
-//     * Comparables, one for explicit Comparators).
-//     */
-//    private static final Comparator<Object> NATURAL_ORDER =
-//            new Comparator<Object>() {
-//        @SuppressWarnings("unchecked")
-//        public int compare(Object first, Object second) {
-//            return ((Comparable<Object>)first).compareTo(second);
-//        }
-//    };
-//
-//    public static void sort(Object[] a) {
-//        sort(a, 0, a.length, NATURAL_ORDER);
-//    }
-//
-//    public static void sort(Object[] a, int fromIndex, int toIndex) {
-//        sort(a, fromIndex, toIndex, NATURAL_ORDER);
-//    }
-
-    /**
      * Sorts the specified array of objects into ascending order, according
      * to the {@linkplain Comparable natural ordering} of its elements.
      * All elements in the array must implement the {@link Comparable}
@@ -1240,7 +1230,7 @@
      *
      * <p>The implementation was adapted from Tim Peters's list sort for Python
      * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
-     * TimSort</a>).  It uses techiques from Peter McIlroy's "Optimistic
+     * TimSort</a>).  It uses techniques from Peter McIlroy's "Optimistic
      * Sorting and Information Theoretic Complexity", in Proceedings of the
      * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
      * January 1993.
@@ -1253,18 +1243,13 @@
      *         {@link Comparable} contract
      */
     public static void sort(Object[] a) {
-        if (LegacyMergeSort.userRequested)
-            legacyMergeSort(a);
-        else
+        // Android-changed: LegacyMergeSort is no longer supported
+        // if (LegacyMergeSort.userRequested)
+        //     legacyMergeSort(a);
+        // else
             ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
     }
 
-    /** To be removed in a future release. */
-    private static void legacyMergeSort(Object[] a) {
-        Object[] aux = a.clone();
-        mergeSort(aux, a, 0, a.length, 0);
-    }
-
     /**
      * Sorts the specified range of the specified array of objects into
      * ascending order, according to the
@@ -1299,7 +1284,7 @@
      *
      * <p>The implementation was adapted from Tim Peters's list sort for Python
      * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
-     * TimSort</a>).  It uses techiques from Peter McIlroy's "Optimistic
+     * TimSort</a>).  It uses techniques from Peter McIlroy's "Optimistic
      * Sorting and Information Theoretic Complexity", in Proceedings of the
      * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
      * January 1993.
@@ -1319,20 +1304,13 @@
      */
     public static void sort(Object[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        if (LegacyMergeSort.userRequested)
-            legacyMergeSort(a, fromIndex, toIndex);
-        else
+        // Android-changed: LegacyMergeSort is no longer supported
+        // if (LegacyMergeSort.userRequested)
+        //     legacyMergeSort(a, fromIndex, toIndex);
+        // else
             ComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0);
     }
 
-    /** To be removed in a future release. */
-    private static void legacyMergeSort(Object[] a,
-                                        int fromIndex, int toIndex) {
-        rangeCheck(a.length, fromIndex, toIndex);
-        Object[] aux = copyOfRange(a, fromIndex, toIndex);
-        mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
-    }
-
     /**
      * Tuning parameter: list size at or below which insertion sort will be
      * used in preference to mergesort.
@@ -1348,6 +1326,7 @@
      * off is the offset to generate corresponding low, high in src
      * To be removed in a future release.
      */
+    @SuppressWarnings({"unchecked", "rawtypes"})
     private static void mergeSort(Object[] src,
                                   Object[] dest,
                                   int low,
@@ -1426,11 +1405,12 @@
      *
      * <p>The implementation was adapted from Tim Peters's list sort for Python
      * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
-     * TimSort</a>).  It uses techiques from Peter McIlroy's "Optimistic
+     * TimSort</a>).  It uses techniques from Peter McIlroy's "Optimistic
      * Sorting and Information Theoretic Complexity", in Proceedings of the
      * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
      * January 1993.
      *
+     * @param <T> the class of the objects to be sorted
      * @param a the array to be sorted
      * @param c the comparator to determine the order of the array.  A
      *        {@code null} value indicates that the elements'
@@ -1444,22 +1424,14 @@
         if (c == null) {
             sort(a);
         } else {
-            if (LegacyMergeSort.userRequested)
-                legacyMergeSort(a, c);
-            else
+            // Android-changed: LegacyMergeSort is no longer supported
+            // if (LegacyMergeSort.userRequested)
+            //     legacyMergeSort(a, c);
+            // else
                 TimSort.sort(a, 0, a.length, c, null, 0, 0);
         }
     }
 
-    /** To be removed in a future release. */
-    private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
-        T[] aux = a.clone();
-        if (c==null)
-            mergeSort(aux, a, 0, a.length, 0);
-        else
-            mergeSort(aux, a, 0, a.length, 0, c);
-    }
-
     /**
      * Sorts the specified range of the specified array of objects according
      * to the order induced by the specified comparator.  The range to be
@@ -1491,11 +1463,12 @@
      *
      * <p>The implementation was adapted from Tim Peters's list sort for Python
      * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt">
-     * TimSort</a>).  It uses techiques from Peter McIlroy's "Optimistic
+     * TimSort</a>).  It uses techniques from Peter McIlroy's "Optimistic
      * Sorting and Information Theoretic Complexity", in Proceedings of the
      * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474,
      * January 1993.
      *
+     * @param <T> the class of the objects to be sorted
      * @param a the array to be sorted
      * @param fromIndex the index of the first element (inclusive) to be
      *        sorted
@@ -1517,89 +1490,14 @@
             sort(a, fromIndex, toIndex);
         } else {
             rangeCheck(a.length, fromIndex, toIndex);
-            if (LegacyMergeSort.userRequested)
-                legacyMergeSort(a, fromIndex, toIndex, c);
-            else
+            // Android-changed: LegacyMergeSort is no longer supported
+            // if (LegacyMergeSort.userRequested)
+            //     legacyMergeSort(a, fromIndex, toIndex, c);
+            // else
                 TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0);
         }
     }
 
-    /** To be removed in a future release. */
-    private static <T> void legacyMergeSort(T[] a, int fromIndex, int toIndex,
-                                            Comparator<? super T> c) {
-        rangeCheck(a.length, fromIndex, toIndex);
-        T[] aux = copyOfRange(a, fromIndex, toIndex);
-        if (c==null)
-            mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
-        else
-            mergeSort(aux, a, fromIndex, toIndex, -fromIndex, c);
-    }
-
-    /**
-     * Src is the source array that starts at index 0
-     * Dest is the (possibly larger) array destination with a possible offset
-     * low is the index in dest to start sorting
-     * high is the end index in dest to end sorting
-     * off is the offset into src corresponding to low in dest
-     * To be removed in a future release.
-     */
-    private static void mergeSort(Object[] src,
-                                  Object[] dest,
-                                  int low, int high, int off,
-                                  Comparator c) {
-        int length = high - low;
-
-        // Insertion sort on smallest arrays
-        if (length < INSERTIONSORT_THRESHOLD) {
-            for (int i=low; i<high; i++)
-                for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
-                    swap(dest, j, j-1);
-            return;
-        }
-
-        // Recursively sort halves of dest into src
-        int destLow  = low;
-        int destHigh = high;
-        low  += off;
-        high += off;
-        int mid = (low + high) >>> 1;
-        mergeSort(dest, src, low, mid, -off, c);
-        mergeSort(dest, src, mid, high, -off, c);
-
-        // If list is already sorted, just copy from src to dest.  This is an
-        // optimization that results in faster sorts for nearly ordered lists.
-        if (c.compare(src[mid-1], src[mid]) <= 0) {
-           System.arraycopy(src, low, dest, destLow, length);
-           return;
-        }
-
-        // Merge sorted halves (now in src) into dest
-        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
-            if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
-                dest[i] = src[p++];
-            else
-                dest[i] = src[q++];
-        }
-    }
-
-    /**
-     * Checks that {@code fromIndex} and {@code toIndex} are in
-     * the range and throws an appropriate exception, if they aren't.
-     */
-    private static void rangeCheck(int length, int fromIndex, int toIndex) {
-        if (fromIndex > toIndex) {
-            throw new IllegalArgumentException(
-                "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
-        }
-        if (fromIndex < 0) {
-            throw new ArrayIndexOutOfBoundsException(fromIndex);
-        }
-        if (toIndex > length) {
-            throw new ArrayIndexOutOfBoundsException(toIndex);
-        }
-    }
-
-
     // Parallel prefix
 
     /**
@@ -2462,7 +2360,9 @@
 
         while (low <= high) {
             int mid = (low + high) >>> 1;
+            @SuppressWarnings("rawtypes")
             Comparable midVal = (Comparable)a[mid];
+            @SuppressWarnings("unchecked")
             int cmp = midVal.compareTo(key);
 
             if (cmp < 0)
@@ -2486,6 +2386,7 @@
      * elements equal to the specified object, there is no guarantee which one
      * will be found.
      *
+     * @param <T> the class of the objects in the array
      * @param a the array to be searched
      * @param key the value to be searched for
      * @param c the comparator by which the array is ordered.  A
@@ -2521,6 +2422,7 @@
      * If the range contains multiple elements equal to the specified object,
      * there is no guarantee which one will be found.
      *
+     * @param <T> the class of the objects in the array
      * @param a the array to be searched
      * @param fromIndex the index of the first element (inclusive) to be
      *          searched
@@ -3192,6 +3094,7 @@
      * is greater than that of the original array.
      * The resulting array is of exactly the same class as the original array.
      *
+     * @param <T> the class of the objects in the array
      * @param original the array to be copied
      * @param newLength the length of the copy to be returned
      * @return a copy of the original array, truncated or padded with nulls
@@ -3200,6 +3103,7 @@
      * @throws NullPointerException if <tt>original</tt> is null
      * @since 1.6
      */
+    @SuppressWarnings("unchecked")
     public static <T> T[] copyOf(T[] original, int newLength) {
         return (T[]) copyOf(original, newLength, original.getClass());
     }
@@ -3214,6 +3118,8 @@
      * is greater than that of the original array.
      * The resulting array is of the class <tt>newType</tt>.
      *
+     * @param <U> the class of the objects in the original array
+     * @param <T> the class of the objects in the returned array
      * @param original the array to be copied
      * @param newLength the length of the copy to be returned
      * @param newType the class of the copy to be returned
@@ -3227,6 +3133,7 @@
      * @since 1.6
      */
     public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
+        @SuppressWarnings("unchecked")
         T[] copy = ((Object)newType == (Object)Object[].class)
             ? (T[]) new Object[newLength]
             : (T[]) Array.newInstance(newType.getComponentType(), newLength);
@@ -3443,6 +3350,7 @@
      * <p>
      * The resulting array is of exactly the same class as the original array.
      *
+     * @param <T> the class of the objects in the array
      * @param original the array from which a range is to be copied
      * @param from the initial index of the range to be copied, inclusive
      * @param to the final index of the range to be copied, exclusive.
@@ -3455,8 +3363,9 @@
      * @throws NullPointerException if <tt>original</tt> is null
      * @since 1.6
      */
+    @SuppressWarnings("unchecked")
     public static <T> T[] copyOfRange(T[] original, int from, int to) {
-        return copyOfRange(original, from, to, (Class<T[]>) original.getClass());
+        return copyOfRange(original, from, to, (Class<? extends T[]>) original.getClass());
     }
 
     /**
@@ -3474,6 +3383,8 @@
      * of the returned array will be <tt>to - from</tt>.
      * The resulting array is of the class <tt>newType</tt>.
      *
+     * @param <U> the class of the objects in the original array
+     * @param <T> the class of the objects in the returned array
      * @param original the array from which a range is to be copied
      * @param from the initial index of the range to be copied, inclusive
      * @param to the final index of the range to be copied, exclusive.
@@ -3494,6 +3405,7 @@
         int newLength = to - from;
         if (newLength < 0)
             throw new IllegalArgumentException(from + " > " + to);
+        @SuppressWarnings("unchecked")
         T[] copy = ((Object)newType == (Object)Object[].class)
             ? (T[]) new Object[newLength]
             : (T[]) Array.newInstance(newType.getComponentType(), newLength);
@@ -3805,10 +3717,12 @@
      *     List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");
      * </pre>
      *
+     * @param <T> the class of the objects in the array
      * @param a the array by which the list will be backed
      * @return a list view of the specified array
      */
     @SafeVarargs
+    @SuppressWarnings("varargs")
     public static <T> List<T> asList(T... a) {
         return new ArrayList<>(a);
     }
@@ -3863,12 +3777,13 @@
 
         @Override
         public int indexOf(Object o) {
-            if (o==null) {
-                for (int i=0; i<a.length; i++)
-                    if (a[i]==null)
+            E[] a = this.a;
+            if (o == null) {
+                for (int i = 0; i < a.length; i++)
+                    if (a[i] == null)
                         return i;
             } else {
-                for (int i=0; i<a.length; i++)
+                for (int i = 0; i < a.length; i++)
                     if (o.equals(a[i]))
                         return i;
             }
@@ -3881,6 +3796,11 @@
         }
 
         @Override
+        public Spliterator<E> spliterator() {
+            return Spliterators.spliterator(a, Spliterator.ORDERED);
+        }
+
+        @Override
         public void forEach(Consumer<? super E> action) {
             Objects.requireNonNull(action);
             for (E e : a) {
@@ -3898,8 +3818,8 @@
         }
 
         @Override
-        public Spliterator<E> spliterator() {
-            return Spliterators.spliterator(a, Spliterator.ORDERED);
+        public void sort(Comparator<? super E> c) {
+            Arrays.sort(a, c);
         }
     }
 
@@ -4192,6 +4112,7 @@
 
         for (Object element : a) {
             int elementHash = 0;
+            // Android-changed: getComponentType() is faster than instanceof()
             if (element != null) {
                 Class<?> cl = element.getClass().getComponentType();
                 if (cl == null)
@@ -4273,6 +4194,7 @@
 
             if (e1 == e2)
                 continue;
+            // Android-changed: Return early if e2 == null
             if (e1 == null || e2 == null)
                 return false;
 
@@ -4286,6 +4208,7 @@
     }
 
     static boolean deepEquals0(Object e1, Object e2) {
+        // Android-changed: getComponentType() is faster than instanceof()
         Class<?> cl1 = e1.getClass().getComponentType();
         Class<?> cl2 = e2.getClass().getComponentType();
 
@@ -4654,7 +4577,7 @@
             if (element == null) {
                 buf.append("null");
             } else {
-                Class eClass = element.getClass();
+                Class<?> eClass = element.getClass();
 
                 if (eClass.isArray()) {
                     if (eClass == byte[].class)
@@ -4691,6 +4614,7 @@
         dejaVu.remove(a);
     }
 
+
     /**
      * Set all elements of the specified array, using the provided
      * generator function to compute each element.
@@ -4846,21 +4770,6 @@
     }
 
     /**
-     * Checks that the range described by {@code offset} and {@code count} doesn't exceed
-     * {@code arrayLength}.
-     *
-     * Android changed.
-     * @hide
-     */
-    public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
-        if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
-            throw new ArrayIndexOutOfBoundsException(arrayLength, offset,
-                    count);
-        }
-    }
-
-
-    /**
      * Returns a {@link Spliterator} covering all of the specified array.
      *
      * <p>The spliterator reports {@link Spliterator#SIZED},
@@ -5019,7 +4928,6 @@
                                         Spliterator.ORDERED | Spliterator.IMMUTABLE);
     }
 
-
     /**
      * Returns a sequential {@link Stream} with the specified array as its
      * source.
diff --git a/ojluni/src/main/java/java/util/Collections.java b/ojluni/src/main/java/java/util/Collections.java
index 5a4de2a..65b9b55 100644
--- a/ojluni/src/main/java/java/util/Collections.java
+++ b/ojluni/src/main/java/java/util/Collections.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
  */
 
 package java.util;
-
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
@@ -35,11 +36,10 @@
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
-import java.util.function.UnaryOperator;
-
 
 /**
  * This class consists exclusively of static methods that operate on or return
@@ -162,9 +162,16 @@
      * @throws IllegalArgumentException (optional) if the implementation
      *         detects that the natural ordering of the list elements is
      *         found to violate the {@link Comparable} contract
+     * @see List#sort(Comparator)
      */
     @SuppressWarnings("unchecked")
     public static <T extends Comparable<? super T>> void sort(List<T> list) {
+        // Android-changed BEGIN: List.sort() is implemented on top of
+        // Collections.sort() rather than the other way around. For backwards
+        // compatibility, Collections.sort() never changes a List's modCount,
+        // but List.sort() implementations may.
+        // was: list.sort(null);
+
         if (list.getClass() == ArrayList.class) {
             Arrays.sort(((ArrayList) list).elementData, 0, list.size());
             return;
@@ -177,6 +184,7 @@
             i.next();
             i.set((T)a[j]);
         }
+        // Android-changed END
     }
 
     /**
@@ -231,9 +239,16 @@
      *         list-iterator does not support the {@code set} operation.
      * @throws IllegalArgumentException (optional) if the comparator is
      *         found to violate the {@link Comparator} contract
+     * @see List#sort(Comparator)
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
     public static <T> void sort(List<T> list, Comparator<? super T> c) {
+        // Android-changed BEGIN: List.sort() is implemented on top of
+        // Collections.sort() rather than the other way around. For backwards
+        // compatibility, Collections.sort() never changes a List's modCount,
+        // but List.sort() implementations may.
+        // was: list.sort(c);
+
         if (list.getClass() == ArrayList.class) {
             Arrays.sort(((ArrayList) list).elementData, 0, list.size(), (Comparator) c);
             return;
@@ -246,6 +261,7 @@
             i.next();
             i.set((T)a[j]);
         }
+        // Android-changed END
     }
 
 
@@ -1152,12 +1168,10 @@
         public void forEach(Consumer<? super E> action) {
             c.forEach(action);
         }
-
         @Override
         public boolean removeIf(Predicate<? super E> filter) {
             throw new UnsupportedOperationException();
         }
-
         @SuppressWarnings("unchecked")
         @Override
         public Spliterator<E> spliterator() {
@@ -1254,6 +1268,96 @@
     }
 
     /**
+     * Returns an unmodifiable view of the specified navigable set.  This method
+     * allows modules to provide users with "read-only" access to internal
+     * navigable sets.  Query operations on the returned navigable set "read
+     * through" to the specified navigable set.  Attempts to modify the returned
+     * navigable set, whether direct, via its iterator, or via its
+     * {@code subSet}, {@code headSet}, or {@code tailSet} views, result in
+     * an {@code UnsupportedOperationException}.<p>
+     *
+     * The returned navigable set will be serializable if the specified
+     * navigable set is serializable.
+     *
+     * @param  <T> the class of the objects in the set
+     * @param s the navigable set for which an unmodifiable view is to be
+     *        returned
+     * @return an unmodifiable view of the specified navigable set
+     * @since 1.8
+     * @hide
+     */
+    public static <T> NavigableSet<T> unmodifiableNavigableSet(NavigableSet<T> s) {
+        return new UnmodifiableNavigableSet<>(s);
+    }
+
+    /**
+     * Wraps a navigable set and disables all of the mutative operations.
+     *
+     * @param <E> type of elements
+     * @serial include
+     */
+    static class UnmodifiableNavigableSet<E>
+                             extends UnmodifiableSortedSet<E>
+                             implements NavigableSet<E>, Serializable {
+
+        private static final long serialVersionUID = -6027448201786391929L;
+
+        /**
+         * A singleton empty unmodifiable navigable set used for
+         * {@link #emptyNavigableSet()}.
+         *
+         * @param <E> type of elements, if there were any, and bounds
+         */
+        private static class EmptyNavigableSet<E> extends UnmodifiableNavigableSet<E>
+            implements Serializable {
+            private static final long serialVersionUID = -6291252904449939134L;
+
+            public EmptyNavigableSet() {
+                super(new TreeSet<E>());
+            }
+
+            private Object readResolve()        { return EMPTY_NAVIGABLE_SET; }
+        }
+
+        @SuppressWarnings("rawtypes")
+        private static final NavigableSet<?> EMPTY_NAVIGABLE_SET =
+                new EmptyNavigableSet<>();
+
+        /**
+         * The instance we are protecting.
+         */
+        private final NavigableSet<E> ns;
+
+        UnmodifiableNavigableSet(NavigableSet<E> s)         {super(s); ns = s;}
+
+        public E lower(E e)                             { return ns.lower(e); }
+        public E floor(E e)                             { return ns.floor(e); }
+        public E ceiling(E e)                         { return ns.ceiling(e); }
+        public E higher(E e)                           { return ns.higher(e); }
+        public E pollFirst()     { throw new UnsupportedOperationException(); }
+        public E pollLast()      { throw new UnsupportedOperationException(); }
+        public NavigableSet<E> descendingSet()
+                 { return new UnmodifiableNavigableSet<>(ns.descendingSet()); }
+        public Iterator<E> descendingIterator()
+                                         { return descendingSet().iterator(); }
+
+        public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
+            return new UnmodifiableNavigableSet<>(
+                ns.subSet(fromElement, fromInclusive, toElement, toInclusive));
+        }
+
+        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            return new UnmodifiableNavigableSet<>(
+                ns.headSet(toElement, inclusive));
+        }
+
+        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            return new UnmodifiableNavigableSet<>(
+                ns.tailSet(fromElement, inclusive));
+        }
+    }
+
+    /**
      * Returns an unmodifiable view of the specified list.  This method allows
      * modules to provide users with "read-only" access to internal
      * lists.  Query operations on the returned list "read through" to the
@@ -1307,6 +1411,7 @@
         public boolean addAll(int index, Collection<? extends E> c) {
             throw new UnsupportedOperationException();
         }
+
         @Override
         public void replaceAll(UnaryOperator<E> operator) {
             throw new UnsupportedOperationException();
@@ -1315,6 +1420,7 @@
         public void sort(Comparator<? super E> c) {
             throw new UnsupportedOperationException();
         }
+
         public ListIterator<E> listIterator()   {return listIterator(0);}
 
         public ListIterator<E> listIterator(final int index) {
@@ -1450,9 +1556,9 @@
             throw new UnsupportedOperationException();
         }
 
-        private transient Set<K> keySet = null;
-        private transient Set<Map.Entry<K,V>> entrySet = null;
-        private transient Collection<V> values = null;
+        private transient Set<K> keySet;
+        private transient Set<Map.Entry<K,V>> entrySet;
+        private transient Collection<V> values;
 
         public Set<K> keySet() {
             if (keySet==null)
@@ -1521,19 +1627,19 @@
 
         @Override
         public V computeIfPresent(K key,
-                                  BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V compute(K key,
-                         BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V merge(K key, V value,
-                       BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
@@ -1559,7 +1665,6 @@
                 return e -> action.accept(new UnmodifiableEntry<>(e));
             }
 
-            // Override default methods in Collection
             public void forEach(Consumer<? super Entry<K, V>> action) {
                 Objects.requireNonNull(action);
                 c.forEach(entryConsumer(action));
@@ -1794,6 +1899,149 @@
         public K lastKey()                             { return sm.lastKey(); }
     }
 
+    /**
+     * Returns an unmodifiable view of the specified navigable map.  This method
+     * allows modules to provide users with "read-only" access to internal
+     * navigable maps.  Query operations on the returned navigable map "read
+     * through" to the specified navigable map.  Attempts to modify the returned
+     * navigable map, whether direct, via its collection views, or via its
+     * {@code subMap}, {@code headMap}, or {@code tailMap} views, result in
+     * an {@code UnsupportedOperationException}.<p>
+     *
+     * The returned navigable map will be serializable if the specified
+     * navigable map is serializable.
+     *
+     * @param <K> the class of the map keys
+     * @param <V> the class of the map values
+     * @param m the navigable map for which an unmodifiable view is to be
+     *        returned
+     * @return an unmodifiable view of the specified navigable map
+     * @since 1.8
+     * @hide
+     */
+    public static <K,V> NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K, ? extends V> m) {
+        return new UnmodifiableNavigableMap<>(m);
+    }
+
+    /**
+     * @serial include
+     */
+    static class UnmodifiableNavigableMap<K,V>
+          extends UnmodifiableSortedMap<K,V>
+          implements NavigableMap<K,V>, Serializable {
+        private static final long serialVersionUID = -4858195264774772197L;
+
+        /**
+         * A class for the {@link EMPTY_NAVIGABLE_MAP} which needs readResolve
+         * to preserve singleton property.
+         *
+         * @param <K> type of keys, if there were any, and of bounds
+         * @param <V> type of values, if there were any
+         */
+        private static class EmptyNavigableMap<K,V> extends UnmodifiableNavigableMap<K,V>
+            implements Serializable {
+
+            private static final long serialVersionUID = -2239321462712562324L;
+
+            EmptyNavigableMap()                       { super(new TreeMap<K,V>()); }
+
+            @Override
+            public NavigableSet<K> navigableKeySet()
+                                                { return emptyNavigableSet(); }
+
+            private Object readResolve()        { return EMPTY_NAVIGABLE_MAP; }
+        }
+
+        /**
+         * Singleton for {@link emptyNavigableMap()} which is also immutable.
+         */
+        private static final EmptyNavigableMap<?,?> EMPTY_NAVIGABLE_MAP =
+            new EmptyNavigableMap<>();
+
+        /**
+         * The instance we wrap and protect.
+         */
+        private final NavigableMap<K, ? extends V> nm;
+
+        UnmodifiableNavigableMap(NavigableMap<K, ? extends V> m)
+                                                            {super(m); nm = m;}
+
+        public K lowerKey(K key)                   { return nm.lowerKey(key); }
+        public K floorKey(K key)                   { return nm.floorKey(key); }
+        public K ceilingKey(K key)               { return nm.ceilingKey(key); }
+        public K higherKey(K key)                 { return nm.higherKey(key); }
+
+        @SuppressWarnings("unchecked")
+        public Entry<K, V> lowerEntry(K key) {
+            Entry<K,V> lower = (Entry<K, V>) nm.lowerEntry(key);
+            return (null != lower)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(lower)
+                : null;
+        }
+
+        @SuppressWarnings("unchecked")
+        public Entry<K, V> floorEntry(K key) {
+            Entry<K,V> floor = (Entry<K, V>) nm.floorEntry(key);
+            return (null != floor)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(floor)
+                : null;
+        }
+
+        @SuppressWarnings("unchecked")
+        public Entry<K, V> ceilingEntry(K key) {
+            Entry<K,V> ceiling = (Entry<K, V>) nm.ceilingEntry(key);
+            return (null != ceiling)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(ceiling)
+                : null;
+        }
+
+
+        @SuppressWarnings("unchecked")
+        public Entry<K, V> higherEntry(K key) {
+            Entry<K,V> higher = (Entry<K, V>) nm.higherEntry(key);
+            return (null != higher)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(higher)
+                : null;
+        }
+
+        @SuppressWarnings("unchecked")
+        public Entry<K, V> firstEntry() {
+            Entry<K,V> first = (Entry<K, V>) nm.firstEntry();
+            return (null != first)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(first)
+                : null;
+        }
+
+        @SuppressWarnings("unchecked")
+        public Entry<K, V> lastEntry() {
+            Entry<K,V> last = (Entry<K, V>) nm.lastEntry();
+            return (null != last)
+                ? new UnmodifiableEntrySet.UnmodifiableEntry<>(last)
+                : null;
+        }
+
+        public Entry<K, V> pollFirstEntry()
+                                 { throw new UnsupportedOperationException(); }
+        public Entry<K, V> pollLastEntry()
+                                 { throw new UnsupportedOperationException(); }
+        public NavigableMap<K, V> descendingMap()
+                       { return unmodifiableNavigableMap(nm.descendingMap()); }
+        public NavigableSet<K> navigableKeySet()
+                     { return unmodifiableNavigableSet(nm.navigableKeySet()); }
+        public NavigableSet<K> descendingKeySet()
+                    { return unmodifiableNavigableSet(nm.descendingKeySet()); }
+
+        public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+            return unmodifiableNavigableMap(
+                nm.subMap(fromKey, fromInclusive, toKey, toInclusive));
+        }
+
+        public NavigableMap<K, V> headMap(K toKey, boolean inclusive)
+             { return unmodifiableNavigableMap(nm.headMap(toKey, inclusive)); }
+        public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive)
+           { return unmodifiableNavigableMap(nm.tailMap(fromKey, inclusive)); }
+    }
+
     // Synch Wrappers
 
     /**
@@ -2078,6 +2326,122 @@
     }
 
     /**
+     * Returns a synchronized (thread-safe) navigable set backed by the
+     * specified navigable set.  In order to guarantee serial access, it is
+     * critical that <strong>all</strong> access to the backing navigable set is
+     * accomplished through the returned navigable set (or its views).<p>
+     *
+     * It is imperative that the user manually synchronize on the returned
+     * navigable set when iterating over it or any of its {@code subSet},
+     * {@code headSet}, or {@code tailSet} views.
+     * <pre>
+     *  NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
+     *      ...
+     *  synchronized (s) {
+     *      Iterator i = s.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * </pre>
+     * or:
+     * <pre>
+     *  NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
+     *  NavigableSet s2 = s.headSet(foo, true);
+     *      ...
+     *  synchronized (s) {  // Note: s, not s2!!!
+     *      Iterator i = s2.iterator(); // Must be in the synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * </pre>
+     * Failure to follow this advice may result in non-deterministic behavior.
+     *
+     * <p>The returned navigable set will be serializable if the specified
+     * navigable set is serializable.
+     *
+     * @param  <T> the class of the objects in the set
+     * @param  s the navigable set to be "wrapped" in a synchronized navigable
+     * set
+     * @return a synchronized view of the specified navigable set
+     * @since 1.8
+     * @hide
+     */
+    public static <T> NavigableSet<T> synchronizedNavigableSet(NavigableSet<T> s) {
+        return new SynchronizedNavigableSet<>(s);
+    }
+
+    /**
+     * @serial include
+     */
+    static class SynchronizedNavigableSet<E>
+        extends SynchronizedSortedSet<E>
+        implements NavigableSet<E>
+    {
+        private static final long serialVersionUID = -5505529816273629798L;
+
+        private final NavigableSet<E> ns;
+
+        SynchronizedNavigableSet(NavigableSet<E> s) {
+            super(s);
+            ns = s;
+        }
+
+        SynchronizedNavigableSet(NavigableSet<E> s, Object mutex) {
+            super(s, mutex);
+            ns = s;
+        }
+        public E lower(E e)      { synchronized (mutex) {return ns.lower(e);} }
+        public E floor(E e)      { synchronized (mutex) {return ns.floor(e);} }
+        public E ceiling(E e)  { synchronized (mutex) {return ns.ceiling(e);} }
+        public E higher(E e)    { synchronized (mutex) {return ns.higher(e);} }
+        public E pollFirst()  { synchronized (mutex) {return ns.pollFirst();} }
+        public E pollLast()    { synchronized (mutex) {return ns.pollLast();} }
+
+        public NavigableSet<E> descendingSet() {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.descendingSet(), mutex);
+            }
+        }
+
+        public Iterator<E> descendingIterator()
+                 { synchronized (mutex) { return descendingSet().iterator(); } }
+
+        public NavigableSet<E> subSet(E fromElement, E toElement) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.subSet(fromElement, true, toElement, false), mutex);
+            }
+        }
+        public NavigableSet<E> headSet(E toElement) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.headSet(toElement, false), mutex);
+            }
+        }
+        public NavigableSet<E> tailSet(E fromElement) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, true), mutex);
+            }
+        }
+
+        public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.subSet(fromElement, fromInclusive, toElement, toInclusive), mutex);
+            }
+        }
+
+        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.headSet(toElement, inclusive), mutex);
+            }
+        }
+
+        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(ns.tailSet(fromElement, inclusive), mutex);
+            }
+        }
+    }
+
+    /**
      * Returns a synchronized (thread-safe) list backed by the specified
      * list.  In order to guarantee serial access, it is critical that
      * <strong>all</strong> access to the backing list is accomplished
@@ -2327,9 +2691,9 @@
             synchronized (mutex) {m.clear();}
         }
 
-        private transient Set<K> keySet = null;
-        private transient Set<Map.Entry<K,V>> entrySet = null;
-        private transient Collection<V> values = null;
+        private transient Set<K> keySet;
+        private transient Set<Map.Entry<K,V>> entrySet;
+        private transient Collection<V> values;
 
         public Set<K> keySet() {
             synchronized (mutex) {
@@ -2398,22 +2762,22 @@
         }
         @Override
         public V computeIfAbsent(K key,
-                                 Function<? super K, ? extends V> mappingFunction) {
+                Function<? super K, ? extends V> mappingFunction) {
             synchronized (mutex) {return m.computeIfAbsent(key, mappingFunction);}
         }
         @Override
         public V computeIfPresent(K key,
-                                  BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             synchronized (mutex) {return m.computeIfPresent(key, remappingFunction);}
         }
         @Override
         public V compute(K key,
-                         BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             synchronized (mutex) {return m.compute(key, remappingFunction);}
         }
         @Override
         public V merge(K key, V value,
-                       BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
             synchronized (mutex) {return m.merge(key, value, remappingFunction);}
         }
 
@@ -2519,6 +2883,167 @@
         }
     }
 
+    /**
+     * Returns a synchronized (thread-safe) navigable map backed by the
+     * specified navigable map.  In order to guarantee serial access, it is
+     * critical that <strong>all</strong> access to the backing navigable map is
+     * accomplished through the returned navigable map (or its views).<p>
+     *
+     * It is imperative that the user manually synchronize on the returned
+     * navigable map when iterating over any of its collection views, or the
+     * collections views of any of its {@code subMap}, {@code headMap} or
+     * {@code tailMap} views.
+     * <pre>
+     *  NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
+     *      ...
+     *  Set s = m.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not s!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * </pre>
+     * or:
+     * <pre>
+     *  NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
+     *  NavigableMap m2 = m.subMap(foo, true, bar, false);
+     *      ...
+     *  Set s2 = m2.keySet();  // Needn't be in synchronized block
+     *      ...
+     *  synchronized (m) {  // Synchronizing on m, not m2 or s2!
+     *      Iterator i = s.iterator(); // Must be in synchronized block
+     *      while (i.hasNext())
+     *          foo(i.next());
+     *  }
+     * </pre>
+     * Failure to follow this advice may result in non-deterministic behavior.
+     *
+     * <p>The returned navigable map will be serializable if the specified
+     * navigable map is serializable.
+     *
+     * @param <K> the class of the map keys
+     * @param <V> the class of the map values
+     * @param  m the navigable map to be "wrapped" in a synchronized navigable
+     *              map
+     * @return a synchronized view of the specified navigable map.
+     * @since 1.8
+     * @hide
+     */
+    public static <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m) {
+        return new SynchronizedNavigableMap<>(m);
+    }
+
+    /**
+     * A synchronized NavigableMap.
+     *
+     * @serial include
+     */
+    static class SynchronizedNavigableMap<K,V>
+        extends SynchronizedSortedMap<K,V>
+        implements NavigableMap<K,V>
+    {
+        private static final long serialVersionUID = 699392247599746807L;
+
+        private final NavigableMap<K,V> nm;
+
+        SynchronizedNavigableMap(NavigableMap<K,V> m) {
+            super(m);
+            nm = m;
+        }
+        SynchronizedNavigableMap(NavigableMap<K,V> m, Object mutex) {
+            super(m, mutex);
+            nm = m;
+        }
+
+        public Entry<K, V> lowerEntry(K key)
+                        { synchronized (mutex) { return nm.lowerEntry(key); } }
+        public K lowerKey(K key)
+                          { synchronized (mutex) { return nm.lowerKey(key); } }
+        public Entry<K, V> floorEntry(K key)
+                        { synchronized (mutex) { return nm.floorEntry(key); } }
+        public K floorKey(K key)
+                          { synchronized (mutex) { return nm.floorKey(key); } }
+        public Entry<K, V> ceilingEntry(K key)
+                      { synchronized (mutex) { return nm.ceilingEntry(key); } }
+        public K ceilingKey(K key)
+                        { synchronized (mutex) { return nm.ceilingKey(key); } }
+        public Entry<K, V> higherEntry(K key)
+                       { synchronized (mutex) { return nm.higherEntry(key); } }
+        public K higherKey(K key)
+                         { synchronized (mutex) { return nm.higherKey(key); } }
+        public Entry<K, V> firstEntry()
+                           { synchronized (mutex) { return nm.firstEntry(); } }
+        public Entry<K, V> lastEntry()
+                            { synchronized (mutex) { return nm.lastEntry(); } }
+        public Entry<K, V> pollFirstEntry()
+                       { synchronized (mutex) { return nm.pollFirstEntry(); } }
+        public Entry<K, V> pollLastEntry()
+                        { synchronized (mutex) { return nm.pollLastEntry(); } }
+
+        public NavigableMap<K, V> descendingMap() {
+            synchronized (mutex) {
+                return
+                    new SynchronizedNavigableMap<>(nm.descendingMap(), mutex);
+            }
+        }
+
+        public NavigableSet<K> keySet() {
+            return navigableKeySet();
+        }
+
+        public NavigableSet<K> navigableKeySet() {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(nm.navigableKeySet(), mutex);
+            }
+        }
+
+        public NavigableSet<K> descendingKeySet() {
+            synchronized (mutex) {
+                return new SynchronizedNavigableSet<>(nm.descendingKeySet(), mutex);
+            }
+        }
+
+
+        public SortedMap<K,V> subMap(K fromKey, K toKey) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableMap<>(
+                    nm.subMap(fromKey, true, toKey, false), mutex);
+            }
+        }
+        public SortedMap<K,V> headMap(K toKey) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableMap<>(nm.headMap(toKey, false), mutex);
+            }
+        }
+        public SortedMap<K,V> tailMap(K fromKey) {
+            synchronized (mutex) {
+        return new SynchronizedNavigableMap<>(nm.tailMap(fromKey, true),mutex);
+            }
+        }
+
+        public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableMap<>(
+                    nm.subMap(fromKey, fromInclusive, toKey, toInclusive), mutex);
+            }
+        }
+
+        public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableMap<>(
+                        nm.headMap(toKey, inclusive), mutex);
+            }
+        }
+
+        public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+            synchronized (mutex) {
+                return new SynchronizedNavigableMap<>(
+                    nm.tailMap(fromKey, inclusive), mutex);
+            }
+        }
+    }
+
     // Dynamically typesafe collection wrappers
 
     /**
@@ -2601,9 +3126,11 @@
         final Collection<E> c;
         final Class<E> type;
 
-        void typeCheck(Object o) {
+        @SuppressWarnings("unchecked")
+        E typeCheck(Object o) {
             if (o != null && !type.isInstance(o))
                 throw new ClassCastException(badElementMsg(o));
+            return (E) o;
         }
 
         private String badElementMsg(Object o) {
@@ -2612,10 +3139,8 @@
         }
 
         CheckedCollection(Collection<E> c, Class<E> type) {
-            if (c==null || type == null)
-                throw new NullPointerException();
-            this.c = c;
-            this.type = type;
+            this.c = Objects.requireNonNull(c, "c");
+            this.type = Objects.requireNonNull(type, "type");
         }
 
         public int size()                 { return c.size(); }
@@ -2648,12 +3173,9 @@
             // Android-note: Should we delegate to it for forEachRemaining ?
         }
 
-        public boolean add(E e) {
-            typeCheck(e);
-            return c.add(e);
-        }
+        public boolean add(E e)          { return c.add(typeCheck(e)); }
 
-        private E[] zeroLengthElementArray = null; // Lazily initialized
+        private E[] zeroLengthElementArray; // Lazily initialized
 
         private E[] zeroLengthElementArray() {
             return zeroLengthElementArray != null ? zeroLengthElementArray :
@@ -2662,7 +3184,7 @@
 
         @SuppressWarnings("unchecked")
         Collection<E> checkedCopyOf(Collection<? extends E> coll) {
-            Object[] a = null;
+            Object[] a;
             try {
                 E[] z = zeroLengthElementArray();
                 a = coll.toArray(z);
@@ -2704,7 +3226,62 @@
         public Stream<E> stream()           {return c.stream();}
         @Override
         public Stream<E> parallelStream()   {return c.parallelStream();}
+    }
 
+    /**
+     * Returns a dynamically typesafe view of the specified queue.
+     * Any attempt to insert an element of the wrong type will result in
+     * an immediate {@link ClassCastException}.  Assuming a queue contains
+     * no incorrectly typed elements prior to the time a dynamically typesafe
+     * view is generated, and that all subsequent access to the queue
+     * takes place through the view, it is <i>guaranteed</i> that the
+     * queue cannot contain an incorrectly typed element.
+     *
+     * <p>A discussion of the use of dynamically typesafe views may be
+     * found in the documentation for the {@link #checkedCollection
+     * checkedCollection} method.
+     *
+     * <p>The returned queue will be serializable if the specified queue
+     * is serializable.
+     *
+     * <p>Since {@code null} is considered to be a value of any reference
+     * type, the returned queue permits insertion of {@code null} elements
+     * whenever the backing queue does.
+     *
+     * @param <E> the class of the objects in the queue
+     * @param queue the queue for which a dynamically typesafe view is to be
+     *             returned
+     * @param type the type of element that {@code queue} is permitted to hold
+     * @return a dynamically typesafe view of the specified queue
+     * @since 1.8
+     * @hide
+     */
+    public static <E> Queue<E> checkedQueue(Queue<E> queue, Class<E> type) {
+        return new CheckedQueue<>(queue, type);
+    }
+
+    /**
+     * @serial include
+     */
+    static class CheckedQueue<E>
+        extends CheckedCollection<E>
+        implements Queue<E>, Serializable
+    {
+        private static final long serialVersionUID = 1433151992604707767L;
+        final Queue<E> queue;
+
+        CheckedQueue(Queue<E> queue, Class<E> elementType) {
+            super(queue, elementType);
+            this.queue = queue;
+        }
+
+        public E element()              {return queue.element();}
+        public boolean equals(Object o) {return o == this || c.equals(o);}
+        public int hashCode()           {return c.hashCode();}
+        public E peek()                 {return queue.peek();}
+        public E poll()                 {return queue.poll();}
+        public E remove()               {return queue.remove();}
+        public boolean offer(E e)       {return queue.offer(typeCheck(e));}
     }
 
     /**
@@ -2815,6 +3392,89 @@
         }
     }
 
+/**
+     * Returns a dynamically typesafe view of the specified navigable set.
+     * Any attempt to insert an element of the wrong type will result in an
+     * immediate {@link ClassCastException}.  Assuming a navigable set
+     * contains no incorrectly typed elements prior to the time a
+     * dynamically typesafe view is generated, and that all subsequent
+     * access to the navigable set takes place through the view, it is
+     * <em>guaranteed</em> that the navigable set cannot contain an incorrectly
+     * typed element.
+     *
+     * <p>A discussion of the use of dynamically typesafe views may be
+     * found in the documentation for the {@link #checkedCollection
+     * checkedCollection} method.
+     *
+     * <p>The returned navigable set will be serializable if the specified
+     * navigable set is serializable.
+     *
+     * <p>Since {@code null} is considered to be a value of any reference
+     * type, the returned navigable set permits insertion of null elements
+     * whenever the backing sorted set does.
+     *
+     * @param <E> the class of the objects in the set
+     * @param s the navigable set for which a dynamically typesafe view is to be
+     *          returned
+     * @param type the type of element that {@code s} is permitted to hold
+     * @return a dynamically typesafe view of the specified navigable set
+     * @since 1.8
+     * @hide
+     */
+    public static <E> NavigableSet<E> checkedNavigableSet(NavigableSet<E> s,
+                                                    Class<E> type) {
+        return new CheckedNavigableSet<>(s, type);
+    }
+
+    /**
+     * @serial include
+     */
+    static class CheckedNavigableSet<E> extends CheckedSortedSet<E>
+        implements NavigableSet<E>, Serializable
+    {
+        private static final long serialVersionUID = -5429120189805438922L;
+
+        private final NavigableSet<E> ns;
+
+        CheckedNavigableSet(NavigableSet<E> s, Class<E> type) {
+            super(s, type);
+            ns = s;
+        }
+
+        public E lower(E e)                             { return ns.lower(e); }
+        public E floor(E e)                             { return ns.floor(e); }
+        public E ceiling(E e)                         { return ns.ceiling(e); }
+        public E higher(E e)                           { return ns.higher(e); }
+        public E pollFirst()                         { return ns.pollFirst(); }
+        public E pollLast()                            {return ns.pollLast(); }
+        public NavigableSet<E> descendingSet()
+                      { return checkedNavigableSet(ns.descendingSet(), type); }
+        public Iterator<E> descendingIterator()
+            {return checkedNavigableSet(ns.descendingSet(), type).iterator(); }
+
+        public NavigableSet<E> subSet(E fromElement, E toElement) {
+            return checkedNavigableSet(ns.subSet(fromElement, true, toElement, false), type);
+        }
+        public NavigableSet<E> headSet(E toElement) {
+            return checkedNavigableSet(ns.headSet(toElement, false), type);
+        }
+        public NavigableSet<E> tailSet(E fromElement) {
+            return checkedNavigableSet(ns.tailSet(fromElement, true), type);
+        }
+
+        public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
+            return checkedNavigableSet(ns.subSet(fromElement, fromInclusive, toElement, toInclusive), type);
+        }
+
+        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            return checkedNavigableSet(ns.headSet(toElement, inclusive), type);
+        }
+
+        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            return checkedNavigableSet(ns.tailSet(fromElement, inclusive), type);
+        }
+    }
+
     /**
      * Returns a dynamically typesafe view of the specified list.
      * Any attempt to insert an element of the wrong type will result in
@@ -2871,13 +3531,11 @@
         public int lastIndexOf(Object o) { return list.lastIndexOf(o); }
 
         public E set(int index, E element) {
-            typeCheck(element);
-            return list.set(index, element);
+            return list.set(index, typeCheck(element));
         }
 
         public void add(int index, E element) {
-            typeCheck(element);
-            list.add(index, element);
+            list.add(index, typeCheck(element));
         }
 
         public boolean addAll(int index, Collection<? extends E> c) {
@@ -2898,13 +3556,11 @@
                 public void remove()         {        i.remove(); }
 
                 public void set(E e) {
-                    typeCheck(e);
-                    i.set(e);
+                    i.set(typeCheck(e));
                 }
 
                 public void add(E e) {
-                    typeCheck(e);
-                    i.add(e);
+                    i.add(typeCheck(e));
                 }
 
                 @Override
@@ -2929,14 +3585,7 @@
         @Override
         public void replaceAll(UnaryOperator<E> operator) {
             Objects.requireNonNull(operator);
-
-            // Android-changed: Modified from OpenJDK 8 code because typeCheck returns void in
-            // OpenJDK 7.
-            list.replaceAll(e -> {
-                    E newValue = operator.apply(e);
-                    typeCheck(newValue);
-                    return newValue;
-            });
+            list.replaceAll(e -> typeCheck(operator.apply(e)));
         }
 
         @Override
@@ -3038,12 +3687,12 @@
 
         private String badKeyMsg(Object key) {
             return "Attempt to insert " + key.getClass() +
-                " key into map with key type " + keyType;
+                    " key into map with key type " + keyType;
         }
 
         private String badValueMsg(Object value) {
             return "Attempt to insert " + value.getClass() +
-                " value into map with value type " + valueType;
+                    " value into map with value type " + valueType;
         }
 
         CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) {
@@ -3091,7 +3740,7 @@
                 m.put(e.getKey(), e.getValue());
         }
 
-        private transient Set<Map.Entry<K,V>> entrySet = null;
+        private transient Set<Map.Entry<K,V>> entrySet;
 
         public Set<Map.Entry<K,V>> entrySet() {
             if (entrySet==null)
@@ -3434,6 +4083,178 @@
         }
     }
 
+    /**
+     * Returns a dynamically typesafe view of the specified navigable map.
+     * Any attempt to insert a mapping whose key or value have the wrong
+     * type will result in an immediate {@link ClassCastException}.
+     * Similarly, any attempt to modify the value currently associated with
+     * a key will result in an immediate {@link ClassCastException},
+     * whether the modification is attempted directly through the map
+     * itself, or through a {@link Map.Entry} instance obtained from the
+     * map's {@link Map#entrySet() entry set} view.
+     *
+     * <p>Assuming a map contains no incorrectly typed keys or values
+     * prior to the time a dynamically typesafe view is generated, and
+     * that all subsequent access to the map takes place through the view
+     * (or one of its collection views), it is <em>guaranteed</em> that the
+     * map cannot contain an incorrectly typed key or value.
+     *
+     * <p>A discussion of the use of dynamically typesafe views may be
+     * found in the documentation for the {@link #checkedCollection
+     * checkedCollection} method.
+     *
+     * <p>The returned map will be serializable if the specified map is
+     * serializable.
+     *
+     * <p>Since {@code null} is considered to be a value of any reference
+     * type, the returned map permits insertion of null keys or values
+     * whenever the backing map does.
+     *
+     * @param <K> type of map keys
+     * @param <V> type of map values
+     * @param m the map for which a dynamically typesafe view is to be
+     *          returned
+     * @param keyType the type of key that {@code m} is permitted to hold
+     * @param valueType the type of value that {@code m} is permitted to hold
+     * @return a dynamically typesafe view of the specified map
+     * @since 1.8
+     * @hide
+     */
+    public static <K,V> NavigableMap<K,V> checkedNavigableMap(NavigableMap<K, V> m,
+                                                        Class<K> keyType,
+                                                        Class<V> valueType) {
+        return new CheckedNavigableMap<>(m, keyType, valueType);
+    }
+
+    /**
+     * @serial include
+     */
+    static class CheckedNavigableMap<K,V> extends CheckedSortedMap<K,V>
+        implements NavigableMap<K,V>, Serializable
+    {
+        private static final long serialVersionUID = -4852462692372534096L;
+
+        private final NavigableMap<K, V> nm;
+
+        CheckedNavigableMap(NavigableMap<K, V> m,
+                         Class<K> keyType, Class<V> valueType) {
+            super(m, keyType, valueType);
+            nm = m;
+        }
+
+        public Comparator<? super K> comparator()   { return nm.comparator(); }
+        public K firstKey()                           { return nm.firstKey(); }
+        public K lastKey()                             { return nm.lastKey(); }
+
+        public Entry<K, V> lowerEntry(K key) {
+            Entry<K,V> lower = nm.lowerEntry(key);
+            return (null != lower)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(lower, valueType)
+                : null;
+        }
+
+        public K lowerKey(K key)                   { return nm.lowerKey(key); }
+
+        public Entry<K, V> floorEntry(K key) {
+            Entry<K,V> floor = nm.floorEntry(key);
+            return (null != floor)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(floor, valueType)
+                : null;
+        }
+
+        public K floorKey(K key)                   { return nm.floorKey(key); }
+
+        public Entry<K, V> ceilingEntry(K key) {
+            Entry<K,V> ceiling = nm.ceilingEntry(key);
+            return (null != ceiling)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(ceiling, valueType)
+                : null;
+        }
+
+        public K ceilingKey(K key)               { return nm.ceilingKey(key); }
+
+        public Entry<K, V> higherEntry(K key) {
+            Entry<K,V> higher = nm.higherEntry(key);
+            return (null != higher)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(higher, valueType)
+                : null;
+        }
+
+        public K higherKey(K key)                 { return nm.higherKey(key); }
+
+        public Entry<K, V> firstEntry() {
+            Entry<K,V> first = nm.firstEntry();
+            return (null != first)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(first, valueType)
+                : null;
+        }
+
+        public Entry<K, V> lastEntry() {
+            Entry<K,V> last = nm.lastEntry();
+            return (null != last)
+                ? new CheckedMap.CheckedEntrySet.CheckedEntry<>(last, valueType)
+                : null;
+        }
+
+        public Entry<K, V> pollFirstEntry() {
+            Entry<K,V> entry = nm.pollFirstEntry();
+            return (null == entry)
+                ? null
+                : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType);
+        }
+
+        public Entry<K, V> pollLastEntry() {
+            Entry<K,V> entry = nm.pollLastEntry();
+            return (null == entry)
+                ? null
+                : new CheckedMap.CheckedEntrySet.CheckedEntry<>(entry, valueType);
+        }
+
+        public NavigableMap<K, V> descendingMap() {
+            return checkedNavigableMap(nm.descendingMap(), keyType, valueType);
+        }
+
+        public NavigableSet<K> keySet() {
+            return navigableKeySet();
+        }
+
+        public NavigableSet<K> navigableKeySet() {
+            return checkedNavigableSet(nm.navigableKeySet(), keyType);
+        }
+
+        public NavigableSet<K> descendingKeySet() {
+            return checkedNavigableSet(nm.descendingKeySet(), keyType);
+        }
+
+        @Override
+        public NavigableMap<K,V> subMap(K fromKey, K toKey) {
+            return checkedNavigableMap(nm.subMap(fromKey, true, toKey, false),
+                                    keyType, valueType);
+        }
+
+        @Override
+        public NavigableMap<K,V> headMap(K toKey) {
+            return checkedNavigableMap(nm.headMap(toKey, false), keyType, valueType);
+        }
+
+        @Override
+        public NavigableMap<K,V> tailMap(K fromKey) {
+            return checkedNavigableMap(nm.tailMap(fromKey, true), keyType, valueType);
+        }
+
+        public NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+            return checkedNavigableMap(nm.subMap(fromKey, fromInclusive, toKey, toInclusive), keyType, valueType);
+        }
+
+        public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+            return checkedNavigableMap(nm.headMap(toKey, inclusive), keyType, valueType);
+        }
+
+        public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+            return checkedNavigableMap(nm.tailMap(fromKey, inclusive), keyType, valueType);
+        }
+    }
+
     // Empty collections
 
     /**
@@ -3623,7 +4444,50 @@
         private Object readResolve() {
             return EMPTY_SET;
         }
+    }
 
+    /**
+     * Returns an empty sorted set (immutable).  This set is serializable.
+     *
+     * <p>This example illustrates the type-safe way to obtain an empty
+     * sorted set:
+     * <pre> {@code
+     *     SortedSet<String> s = Collections.emptySortedSet();
+     * }</pre>
+     *
+     * @implNote Implementations of this method need not create a separate
+     * {@code SortedSet} object for each call.
+     *
+     * @param <E> type of elements, if there were any, in the set
+     * @return the empty sorted set
+     * @since 1.8
+     * @hide
+     */
+    @SuppressWarnings("unchecked")
+    public static <E> SortedSet<E> emptySortedSet() {
+        return (SortedSet<E>) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET;
+    }
+
+    /**
+     * Returns an empty navigable set (immutable).  This set is serializable.
+     *
+     * <p>This example illustrates the type-safe way to obtain an empty
+     * navigable set:
+     * <pre> {@code
+     *     NavigableSet<String> s = Collections.emptyNavigableSet();
+     * }</pre>
+     *
+     * @implNote Implementations of this method need not
+     * create a separate {@code NavigableSet} object for each call.
+     *
+     * @param <E> type of elements, if there were any, in the set
+     * @return the empty navigable set
+     * @since 1.8
+     * @hide
+     */
+    @SuppressWarnings("unchecked")
+    public static <E> NavigableSet<E> emptyNavigableSet() {
+        return (NavigableSet<E>) UnmodifiableNavigableSet.EMPTY_NAVIGABLE_SET;
     }
 
     /**
@@ -3641,10 +4505,12 @@
      * <pre>
      *     List&lt;String&gt; s = Collections.emptyList();
      * </pre>
-     * Implementation note:  Implementations of this method need not
-     * create a separate <tt>List</tt> object for each call.   Using this
-     * method is likely to have comparable cost to using the like-named
-     * field.  (Unlike this method, the field does not provide type safety.)
+     *
+     * @implNote
+     * Implementations of this method need not create a separate <tt>List</tt>
+     * object for each call.   Using this method is likely to have comparable
+     * cost to using the like-named field.  (Unlike this method, the field does
+     * not provide type safety.)
      *
      * @param <T> type of elements, if there were any, in the list
      * @return an empty immutable list
@@ -3701,6 +4567,13 @@
             Objects.requireNonNull(filter);
             return false;
         }
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            Objects.requireNonNull(operator);
+        }
+        @Override
+        public void sort(Comparator<? super E> c) {
+        }
 
         // Override default methods in Collection
         @Override
@@ -3711,15 +4584,6 @@
         @Override
         public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
 
-        @Override
-        public void replaceAll(UnaryOperator<E> operator) {
-            Objects.requireNonNull(operator);
-        }
-        @Override
-        public void sort(Comparator<? super E> c) {
-        }
-
-
         // Preserves singleton property
         private Object readResolve() {
             return EMPTY_LIST;
@@ -3759,6 +4623,50 @@
     }
 
     /**
+     * Returns an empty sorted map (immutable).  This map is serializable.
+     *
+     * <p>This example illustrates the type-safe way to obtain an empty map:
+     * <pre> {@code
+     *     SortedMap<String, Date> s = Collections.emptySortedMap();
+     * }</pre>
+     *
+     * @implNote Implementations of this method need not create a separate
+     * {@code SortedMap} object for each call.
+     *
+     * @param <K> the class of the map keys
+     * @param <V> the class of the map values
+     * @return an empty sorted map
+     * @since 1.8
+     * @hide
+     */
+    @SuppressWarnings("unchecked")
+    public static final <K,V> SortedMap<K,V> emptySortedMap() {
+        return (SortedMap<K,V>) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP;
+    }
+
+    /**
+     * Returns an empty navigable map (immutable).  This map is serializable.
+     *
+     * <p>This example illustrates the type-safe way to obtain an empty map:
+     * <pre> {@code
+     *     NavigableMap<String, Date> s = Collections.emptyNavigableMap();
+     * }</pre>
+     *
+     * @implNote Implementations of this method need not create a separate
+     * {@code NavigableMap} object for each call.
+     *
+     * @param <K> the class of the map keys
+     * @param <V> the class of the map values
+     * @return an empty navigable map
+     * @since 1.8
+     * @hide
+     */
+    @SuppressWarnings("unchecked")
+    public static final <K,V> NavigableMap<K,V> emptyNavigableMap() {
+        return (NavigableMap<K,V>) UnmodifiableNavigableMap.EMPTY_NAVIGABLE_MAP;
+    }
+
+    /**
      * @serial include
      */
     private static class EmptyMap<K,V>
@@ -3821,25 +4729,25 @@
 
         @Override
         public V computeIfAbsent(K key,
-                                 Function<? super K, ? extends V> mappingFunction) {
+                Function<? super K, ? extends V> mappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V computeIfPresent(K key,
-                                  BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V compute(K key,
-                         BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V merge(K key, V value,
-                       BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
@@ -4022,15 +4930,16 @@
             throw new UnsupportedOperationException();
         }
         @Override
-        public Spliterator<E> spliterator() {
-            return singletonSpliterator(element);
-        }
         public void replaceAll(UnaryOperator<E> operator) {
             throw new UnsupportedOperationException();
         }
         @Override
         public void sort(Comparator<? super E> c) {
         }
+        @Override
+        public Spliterator<E> spliterator() {
+            return singletonSpliterator(element);
+        }
     }
 
     /**
@@ -4065,19 +4974,15 @@
             v = value;
         }
 
-        public int size()                          {return 1;}
+        public int size()                                           {return 1;}
+        public boolean isEmpty()                                {return false;}
+        public boolean containsKey(Object key)             {return eq(key, k);}
+        public boolean containsValue(Object value)       {return eq(value, v);}
+        public V get(Object key)              {return (eq(key, k) ? v : null);}
 
-        public boolean isEmpty()                   {return false;}
-
-        public boolean containsKey(Object key)     {return eq(key, k);}
-
-        public boolean containsValue(Object value) {return eq(value, v);}
-
-        public V get(Object key)                   {return (eq(key, k) ? v : null);}
-
-        private transient Set<K> keySet = null;
-        private transient Set<Map.Entry<K,V>> entrySet = null;
-        private transient Collection<V> values = null;
+        private transient Set<K> keySet;
+        private transient Set<Map.Entry<K,V>> entrySet;
+        private transient Collection<V> values;
 
         public Set<K> keySet() {
             if (keySet==null)
@@ -4136,25 +5041,25 @@
 
         @Override
         public V computeIfAbsent(K key,
-                                 Function<? super K, ? extends V> mappingFunction) {
+                Function<? super K, ? extends V> mappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V computeIfPresent(K key,
-                                  BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V compute(K key,
-                         BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
 
         @Override
         public V merge(K key, V value,
-                       BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+                BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
     }
@@ -4753,7 +5658,6 @@
         public boolean removeIf(Predicate<? super E> filter) {
             return q.removeIf(filter);
         }
-
         @Override
         public Spliterator<E> spliterator() {return q.spliterator();}
         @Override
diff --git a/ojluni/src/main/java/java/util/Locale.java b/ojluni/src/main/java/java/util/Locale.java
index 5d1a775..1bbac52 100644
--- a/ojluni/src/main/java/java/util/Locale.java
+++ b/ojluni/src/main/java/java/util/Locale.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -46,13 +46,9 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.security.AccessController;
 import java.text.MessageFormat;
-import java.util.spi.LocaleNameProvider;
 import libcore.icu.ICU;
 
-import sun.security.action.GetPropertyAction;
-import sun.util.LocaleServiceProviderPool;
 import sun.util.locale.BaseLocale;
 import sun.util.locale.InternalLocaleBuilder;
 import sun.util.locale.LanguageTag;
@@ -61,7 +57,6 @@
 import sun.util.locale.LocaleSyntaxException;
 import sun.util.locale.LocaleUtils;
 import sun.util.locale.ParseStatus;
-import sun.util.locale.UnicodeLocaleExtension;
 
 /**
  * A <code>Locale</code> object represents a specific geographical, political,
@@ -82,7 +77,7 @@
  * described below.
  *
  * <dl>
- *   <dt><a name="def_language"></a><b>language</b></dt>
+ *   <dt><a name="def_language"><b>language</b></a></dt>
  *
  *   <dd>ISO 639 alpha-2 or alpha-3 language code, or registered
  *   language subtags up to 8 alpha letters (for future enhancements).
@@ -90,51 +85,51 @@
  *   alpha-2 code must be used.  You can find a full list of valid
  *   language codes in the IANA Language Subtag Registry (search for
  *   "Type: language").  The language field is case insensitive, but
- *   <code>Locale</code> always canonicalizes to lower case.</dd><br>
+ *   <code>Locale</code> always canonicalizes to lower case.</dd>
  *
  *   <dd>Well-formed language values have the form
  *   <code>[a-zA-Z]{2,8}</code>.  Note that this is not the the full
  *   BCP47 language production, since it excludes extlang.  They are
  *   not needed since modern three-letter language codes replace
- *   them.</dd><br>
+ *   them.</dd>
  *
- *   <dd>Example: "en" (English), "ja" (Japanese), "kok" (Konkani)</dd><br>
+ *   <dd>Example: "en" (English), "ja" (Japanese), "kok" (Konkani)</dd>
  *
- *   <dt><a name="def_script"/></a><b>script</b></dt>
+ *   <dt><a name="def_script"><b>script</b></a></dt>
  *
  *   <dd>ISO 15924 alpha-4 script code.  You can find a full list of
  *   valid script codes in the IANA Language Subtag Registry (search
  *   for "Type: script").  The script field is case insensitive, but
  *   <code>Locale</code> always canonicalizes to title case (the first
  *   letter is upper case and the rest of the letters are lower
- *   case).</dd><br>
+ *   case).</dd>
  *
  *   <dd>Well-formed script values have the form
- *   <code>[a-zA-Z]{4}</code></dd><br>
+ *   <code>[a-zA-Z]{4}</code></dd>
  *
- *   <dd>Example: "Latn" (Latin), "Cyrl" (Cyrillic)</dd><br>
+ *   <dd>Example: "Latn" (Latin), "Cyrl" (Cyrillic)</dd>
  *
- *   <dt><a name="def_region"></a><b>country (region)</b></dt>
+ *   <dt><a name="def_region"><b>country (region)</b></a></dt>
  *
  *   <dd>ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code.
  *   You can find a full list of valid country and region codes in the
  *   IANA Language Subtag Registry (search for "Type: region").  The
  *   country (region) field is case insensitive, but
- *   <code>Locale</code> always canonicalizes to upper case.</dd><br>
+ *   <code>Locale</code> always canonicalizes to upper case.</dd>
  *
  *   <dd>Well-formed country/region values have
- *   the form <code>[a-zA-Z]{2} | [0-9]{3}</code></dd><br>
+ *   the form <code>[a-zA-Z]{2} | [0-9]{3}</code></dd>
  *
  *   <dd>Example: "US" (United States), "FR" (France), "029"
- *   (Caribbean)</dd><br>
+ *   (Caribbean)</dd>
  *
- *   <dt><a name="def_variant"></a><b>variant</b></dt>
+ *   <dt><a name="def_variant"><b>variant</b></a></dt>
  *
  *   <dd>Any arbitrary value used to indicate a variation of a
  *   <code>Locale</code>.  Where there are two or more variant values
  *   each indicating its own semantics, these values should be ordered
  *   by importance, with most important first, separated by
- *   underscore('_').  The variant field is case sensitive.</dd><br>
+ *   underscore('_').  The variant field is case sensitive.</dd>
  *
  *   <dd>Note: IETF BCP 47 places syntactic restrictions on variant
  *   subtags.  Also BCP 47 subtags are strictly used to indicate
@@ -150,16 +145,16 @@
  *   cultural behaviors such as calendar type or number script.  In
  *   BCP 47 this kind of information, which does not identify the
  *   language, is supported by extension subtags or private use
- *   subtags.</dd><br>
+ *   subtags.</dd>
  *
  *   <dd>Well-formed variant values have the form <code>SUBTAG
  *   (('_'|'-') SUBTAG)*</code> where <code>SUBTAG =
  *   [0-9][0-9a-zA-Z]{3} | [0-9a-zA-Z]{5,8}</code>. (Note: BCP 47 only
- *   uses hyphen ('-') as a delimiter, this is more lenient).</dd><br>
+ *   uses hyphen ('-') as a delimiter, this is more lenient).</dd>
  *
- *   <dd>Example: "polyton" (Polytonic Greek), "POSIX"</dd><br>
+ *   <dd>Example: "polyton" (Polytonic Greek), "POSIX"</dd>
  *
- *   <dt><a name="def_extensions"></a><b>extensions</b></dt>
+ *   <dt><a name="def_extensions"><b>extensions</b></a></dt>
  *
  *   <dd>A map from single character keys to string values, indicating
  *   extensions apart from language identification.  The extensions in
@@ -167,14 +162,14 @@
  *   extension subtags and private use subtags. The extensions are
  *   case insensitive, but <code>Locale</code> canonicalizes all
  *   extension keys and values to lower case. Note that extensions
- *   cannot have empty values.</dd><br>
+ *   cannot have empty values.</dd>
  *
  *   <dd>Well-formed keys are single characters from the set
  *   <code>[0-9a-zA-Z]</code>.  Well-formed values have the form
  *   <code>SUBTAG ('-' SUBTAG)*</code> where for the key 'x'
  *   <code>SUBTAG = [0-9a-zA-Z]{1,8}</code> and for other keys
  *   <code>SUBTAG = [0-9a-zA-Z]{2,8}</code> (that is, 'x' allows
- *   single-character subtags).</dd><br>
+ *   single-character subtags).</dd>
  *
  *   <dd>Example: key="u"/value="ca-japanese" (Japanese Calendar),
  *   key="x"/value="java-1-7"</dd>
@@ -187,7 +182,7 @@
  * requirement (is well-formed), but does not validate the value
  * itself.  See {@link Builder} for details.
  *
- * <h4><a name="def_locale_extension"></a>Unicode locale/language extension</h4>
+ * <h3><a name="def_locale_extension">Unicode locale/language extension</a></h3>
  *
  * <p>UTS#35, "Unicode Locale Data Markup Language" defines optional
  * attributes and keywords to override or refine the default behavior
@@ -278,7 +273,8 @@
  * you can use <code>getDisplayLanguage</code> to get the name of
  * the language suitable for displaying to the user. Interestingly,
  * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
- * and have two versions: one that uses the default locale and one
+ * and have two versions: one that uses the default
+ * {@link Locale.Category#DISPLAY DISPLAY} locale and one
  * that uses the locale specified as an argument.
  *
  * <p>The Java Platform provides a number of classes that perform locale-sensitive
@@ -296,7 +292,8 @@
  * </pre>
  * </blockquote>
  * Each of these methods has two variants; one with an explicit locale
- * and one without; the latter uses the default locale:
+ * and one without; the latter uses the default
+ * {@link Locale.Category#FORMAT FORMAT} locale:
  * <blockquote>
  * <pre>
  *     NumberFormat.getInstance(myLocale)
@@ -334,7 +331,7 @@
  * Clients desiring a string representation of the complete locale can
  * then always rely on <code>toLanguageTag</code> for this purpose.
  *
- * <h5><a name="special_cases_constructor"></a>Special cases</h5>
+ * <h5><a name="special_cases_constructor">Special cases</a></h5>
  *
  * <p>For compatibility reasons, two
  * non-conforming locales are treated as special cases.  These are
@@ -816,10 +813,6 @@
      */
     public static Locale getDefault() {
         // do not synchronize this method - see 4071298
-        // it's OK if more than one default locale happens to be created
-        if (defaultLocale == null) {
-            defaultLocale = initDefault();
-        }
         return defaultLocale;
     }
 
@@ -841,16 +834,23 @@
      */
     public static Locale getDefault(Locale.Category category) {
         // do not synchronize this method - see 4071298
-        // it's OK if more than one default locale happens to be created
         switch (category) {
         case DISPLAY:
             if (defaultDisplayLocale == null) {
-                defaultDisplayLocale = initDefault(category);
+                synchronized(Locale.class) {
+                    if (defaultDisplayLocale == null) {
+                        defaultDisplayLocale = initDefault(category);
+                    }
+                }
             }
             return defaultDisplayLocale;
         case FORMAT:
             if (defaultFormatLocale == null) {
-                defaultFormatLocale = initDefault(category);
+                synchronized(Locale.class) {
+                    if (defaultFormatLocale == null) {
+                        defaultFormatLocale = initDefault(category);
+                    }
+                }
             }
             return defaultFormatLocale;
         default:
@@ -859,6 +859,10 @@
         return getDefault();
     }
 
+    // Android-changed BEGIN:
+    //  1.) In initDefault(), user.locale gets priority
+    //  2.) In both initDefault methods, use System.getProperty() instead
+    //      of legacy AccessController / GetPropertyAction security code.
     /**
      * @hide visible for testing.
      */
@@ -890,13 +894,11 @@
             country = System.getProperty("user.country", "");
             variant = System.getProperty("user.variant", "");
         }
+
         return getInstance(language, script, country, variant, null);
     }
 
     private static Locale initDefault(Locale.Category category) {
-        // make sure defaultLocale is initialized
-        final Locale defaultLocale = getDefault();
-
         return getInstance(
             System.getProperty(category.languageKey, defaultLocale.getLanguage()),
             System.getProperty(category.scriptKey, defaultLocale.getScript()),
@@ -904,6 +906,7 @@
             System.getProperty(category.variantKey, defaultLocale.getVariant()),
             null);
     }
+    // Android-changed END
 
     /**
      * Sets the default locale for this instance of the Java Virtual Machine.
@@ -937,6 +940,7 @@
         setDefault(Category.DISPLAY, newLocale);
         setDefault(Category.FORMAT, newLocale);
         defaultLocale = newLocale;
+        // Android-added: Keep ICU state in sync with java.util.
         ICU.setDefaultLocale(newLocale.toLanguageTag());
     }
 
@@ -990,18 +994,15 @@
         }
     }
 
+    // Android-changed: Removed references to LocaleServiceProvider.
     /**
      * Returns an array of all installed locales.
-     * The returned array represents the union of locales supported
-     * by the Java runtime environment and by installed
-     * {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider}
-     * implementations.  It must contain at least a <code>Locale</code>
-     * instance equal to {@link java.util.Locale#US Locale.US}.
      *
      * @return An array of installed locales.
      */
     public static Locale[] getAvailableLocales() {
-        return LocaleServiceProviderPool.getAllAvailableLocales();
+        // Android-changed: Removed used of LocaleServiceProviderPool. Switched to use ICU.
+        return ICU.getAvailableLocales();
     }
 
     /**
@@ -1012,9 +1013,11 @@
      * country (region), such as 3-letter numeric UN M.49 area codes.
      * Therefore, the list returned by this method does not contain ALL valid
      * codes that can be used to create Locales.
+     *
+     * @return An array of ISO 3166 two-letter country codes.
      */
     public static String[] getISOCountries() {
-        // Android-changed: Use ICU.
+        // Android-changed: Switched to use ICU.
         return ICU.getISOCountries();
     }
 
@@ -1031,9 +1034,11 @@
      * 8 characters in length.  Therefore, the list returned by this method does
      * not contain ALL valid codes that can be used to create Locales.
      * </ul>
+     *
+     * @return Am array of ISO 639 two-letter language codes.
      */
     public static String[] getISOLanguages() {
-        // Android-changed: Use ICU.
+        // Android-changed: Switched to use ICU.
         return ICU.getISOLanguages();
     }
 
@@ -1097,6 +1102,30 @@
     }
 
     /**
+     * Returns {@code true} if this {@code Locale} has any <a href="#def_extensions">
+     * extensions</a>.
+     *
+     * @return {@code true} if this {@code Locale} has any extensions
+     * @since 1.8
+     */
+    public boolean hasExtensions() {
+        return localeExtensions != null;
+    }
+
+    /**
+     * Returns a copy of this {@code Locale} with no <a href="#def_extensions">
+     * extensions</a>. If this {@code Locale} has no extensions, this {@code Locale}
+     * is returned.
+     *
+     * @return a copy of this {@code Locale} with no extensions, or {@code this}
+     *         if {@code this} has no extensions
+     * @since 1.8
+     */
+    public Locale stripExtensions() {
+        return hasExtensions() ? Locale.getInstance(baseLocale, null) : this;
+    }
+
+    /**
      * Returns the extension (or private use) value associated with
      * the specified key, or null if there is no extension
      * associated with the key. To be well-formed, the key must be one
@@ -1115,7 +1144,7 @@
         if (!LocaleExtensions.isValidKey(key)) {
             throw new IllegalArgumentException("Ill-formed extension key: " + key);
         }
-        return (localeExtensions == null) ? null : localeExtensions.getExtensionValue(key);
+        return hasExtensions() ? localeExtensions.getExtensionValue(key) : null;
     }
 
     /**
@@ -1128,7 +1157,7 @@
      * @since 1.7
      */
     public Set<Character> getExtensionKeys() {
-        if (localeExtensions == null) {
+        if (!hasExtensions()) {
             return Collections.emptySet();
         }
         return localeExtensions.getKeys();
@@ -1143,7 +1172,7 @@
      * @since 1.7
      */
     public Set<String> getUnicodeLocaleAttributes() {
-        if (localeExtensions == null) {
+        if (!hasExtensions()) {
             return Collections.emptySet();
         }
         return localeExtensions.getUnicodeLocaleAttributes();
@@ -1164,10 +1193,10 @@
      * @since 1.7
      */
     public String getUnicodeLocaleType(String key) {
-        if (!UnicodeLocaleExtension.isKey(key)) {
+        if (!isUnicodeExtensionKey(key)) {
             throw new IllegalArgumentException("Ill-formed Unicode locale key: " + key);
         }
-        return (localeExtensions == null) ? null : localeExtensions.getUnicodeLocaleType(key);
+        return hasExtensions() ? localeExtensions.getUnicodeLocaleType(key) : null;
     }
 
     /**
@@ -1208,7 +1237,7 @@
      * Returns a string representation of this <code>Locale</code>
      * object, consisting of language, country, variant, script,
      * and extensions as below:
-     * <p><blockquote>
+     * <blockquote>
      * language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
      * </blockquote>
      *
@@ -1232,15 +1261,15 @@
      * fields only.  To represent a Locale as a String for interchange purposes, use
      * {@link #toLanguageTag}.
      *
-     * <p>Examples: <ul><tt>
-     * <li>en
-     * <li>de_DE
-     * <li>_GB
-     * <li>en_US_WIN
-     * <li>de__POSIX
-     * <li>zh_CN_#Hans
-     * <li>zh_TW_#Hant-x-java
-     * <li>th_TH_TH_#u-nu-thai</tt></ul>
+     * <p>Examples: <ul>
+     * <li><tt>en</tt></li>
+     * <li><tt>de_DE</tt></li>
+     * <li><tt>_GB</tt></li>
+     * <li><tt>en_US_WIN</tt></li>
+     * <li><tt>de__POSIX</tt></li>
+     * <li><tt>zh_CN_#Hans</tt></li>
+     * <li><tt>zh_TW_#Hant-x-java</tt></li>
+     * <li><tt>th_TH_TH_#u-nu-thai</tt></li></ul>
      *
      * @return A string representation of the Locale, for debugging.
      * @see #getDisplayName
@@ -1348,6 +1377,10 @@
      * @since 1.7
      */
     public String toLanguageTag() {
+        if (languageTag != null) {
+            return languageTag;
+        }
+
         LanguageTag tag = LanguageTag.parseLocale(baseLocale, localeExtensions);
         StringBuilder buf = new StringBuilder();
 
@@ -1391,7 +1424,13 @@
             buf.append(subtag);
         }
 
-        return buf.toString();
+        String langTag = buf.toString();
+        synchronized (this) {
+            if (languageTag == null) {
+                languageTag = langTag;
+            }
+        }
+        return languageTag;
     }
 
     /**
@@ -1449,7 +1488,7 @@
      *    // returns "ja-JP-u-ca-japanese-x-lvariant-JP"
      *    Locale.forLanguageTag("th-TH-x-lvariant-TH").toLanguageTag();
      *    // returns "th-TH-u-nu-thai-x-lvariant-TH"
-     * <pre></ul>
+     * </pre></ul>
      *
      * <p>This implements the 'Language-Tag' production of BCP47, and
      * so supports grandfathered (regular and irregular) as well as
@@ -1460,7 +1499,7 @@
      *
      * <p>Grandfathered tags with canonical replacements are as follows:
      *
-     * <table>
+     * <table summary="Grandfathered tags with canonical replacements">
      * <tbody align="center">
      * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>modern replacement</th></tr>
      * <tr><td>art-lojban</td><td>&nbsp;</td><td>jbo</td></tr>
@@ -1489,7 +1528,7 @@
      * <p>Grandfathered tags with no modern replacement will be
      * converted as follows:
      *
-     * <table>
+     * <table summary="Grandfathered tags with no modern replacement">
      * <tbody align="center">
      * <tr><th>grandfathered tag</th><th>&nbsp;</th><th>converts to</th></tr>
      * <tr><td>cel-gaulish</td><td>&nbsp;</td><td>xtg-x-cel-gaulish</td></tr>
@@ -1542,21 +1581,26 @@
      * three-letter language abbreviation is not available for this locale.
      */
     public String getISO3Language() throws MissingResourceException {
-        // Android-changed: Use ICU.getIso3Language. Also return "" for empty languages
-        // for the sake of backwards compatibility.
         String lang = baseLocale.getLanguage();
         if (lang.length() == 3) {
             return lang;
-        } else if (lang.isEmpty()) {
+        }
+        // Android-added BEGIN
+        // return "" for empty languages for the sake of backwards compatibility.
+        else if (lang.isEmpty()) {
             return "";
         }
+        // Android-added END
 
+        // Android-changed BEGIN: Use ICU.
+        // String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
+        // if (language3 == null) {
         String language3 = ICU.getISO3Language(lang);
         if (!lang.isEmpty() && language3.isEmpty()) {
+        // Android-changed END
             throw new MissingResourceException("Couldn't find 3-letter language code for "
                     + lang, "FormatData_" + toString(), "ShortLanguage");
         }
-
         return language3;
     }
 
@@ -1574,7 +1618,7 @@
      * three-letter country abbreviation is not available for this locale.
      */
     public String getISO3Country() throws MissingResourceException {
-        // Android changed: Use.getIso3Country. Also return "" for missing regions.
+        // Android-changed BEGIN: Use ICU. Also return "" for missing regions.
         final String region = baseLocale.getRegion();
         // Note that this will return an UN.M49 region code
         if (region.length() == 3) {
@@ -1589,25 +1633,34 @@
             throw new MissingResourceException("Couldn't find 3-letter country code for "
                     + baseLocale.getRegion(), "FormatData_" + toString(), "ShortCountry");
         }
+        // Android-changed END
         return country3;
     }
 
     /**
      * Returns a name for the locale's language that is appropriate for display to the
      * user.
-     * If possible, the name returned will be localized for the default locale.
-     * For example, if the locale is fr_FR and the default locale
+     * If possible, the name returned will be localized for the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale.
+     * For example, if the locale is fr_FR and the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale
      * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
-     * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
-     * If the name returned cannot be localized for the default locale,
+     * the default {@link Locale.Category#DISPLAY DISPLAY} locale is fr_FR,
+     * getDisplayLanguage() will return "anglais".
+     * If the name returned cannot be localized for the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale,
      * (say, we don't have a Japanese name for Croatian),
      * this function falls back on the English name, and uses the ISO code as a last-resort
      * value.  If the locale doesn't specify a language, this function returns the empty string.
+     *
+     * @return The name of the display language.
      */
     public final String getDisplayLanguage() {
         return getDisplayLanguage(getDefault(Category.DISPLAY));
     }
 
+    // Android-changed BEGIN: Use ICU; documentation; backwards compatibility hacks;
+    // added private helper methods.
     /**
      * Returns the name of this locale's language, localized to {@code locale}.
      * If the language name is unknown, the language code is returned.
@@ -1672,56 +1725,73 @@
 
         return true;
     }
+    // Android-changed END
 
     /**
      * Returns a name for the the locale's script that is appropriate for display to
-     * the user. If possible, the name will be localized for the default locale.  Returns
+     * the user. If possible, the name will be localized for the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale.  Returns
      * the empty string if this locale doesn't specify a script code.
      *
-     * @return the display name of the script code for the current default locale
+     * @return the display name of the script code for the current default
+     *     {@link Locale.Category#DISPLAY DISPLAY} locale
      * @since 1.7
      */
     public String getDisplayScript() {
-        return getDisplayScript(getDefault());
+        return getDisplayScript(getDefault(Category.DISPLAY));
     }
 
     /**
-     * Returns the name of this locale's script code, localized to {@link Locale}. If the
-     * script code is unknown, the return value of this method is the same as that of
-     * {@link #getScript()}.
+     * Returns a name for the locale's script that is appropriate
+     * for display to the user. If possible, the name will be
+     * localized for the given locale. Returns the empty string if
+     * this locale doesn't specify a script code.
      *
+     * @param inLocale The locale for which to retrieve the display script.
+     * @return the display name of the script code for the current default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale
+     * @throws NullPointerException if <code>inLocale</code> is <code>null</code>
      * @since 1.7
      */
-    public String getDisplayScript(Locale locale) {
+    public String getDisplayScript(Locale inLocale) {
+        // Android-changed BEGIN: Use ICU.
         String scriptCode = baseLocale.getScript();
         if (scriptCode.isEmpty()) {
             return "";
         }
 
-        String result = ICU.getDisplayScript(this, locale);
+        String result = ICU.getDisplayScript(this, inLocale);
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = ICU.getDisplayScript(this, Locale.getDefault());
+            result = ICU.getDisplayScript(this, Locale.getDefault(Category.DISPLAY));
         }
 
         return result;
-
+        // Android-changed END
     }
 
     /**
      * Returns a name for the locale's country that is appropriate for display to the
      * user.
-     * If possible, the name returned will be localized for the default locale.
-     * For example, if the locale is fr_FR and the default locale
+     * If possible, the name returned will be localized for the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale.
+     * For example, if the locale is fr_FR and the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale
      * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
-     * the default locale is fr_FR, getDisplayCountry() will return "Etats-Unis".
-     * If the name returned cannot be localized for the default locale,
+     * the default {@link Locale.Category#DISPLAY DISPLAY} locale is fr_FR,
+     * getDisplayCountry() will return "Etats-Unis".
+     * If the name returned cannot be localized for the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale,
      * (say, we don't have a Japanese name for Croatia),
      * this function falls back on the English name, and uses the ISO code as a last-resort
      * value.  If the locale doesn't specify a country, this function returns the empty string.
+     *
+     * @return The name of the country appropriate to the locale.
      */
     public final String getDisplayCountry() {
         return getDisplayCountry(getDefault(Category.DISPLAY));
     }
+
+    // Android-changed BEGIN: Use ICU; documentation; added private helper methods.
     /**
      * Returns the name of this locale's country, localized to {@code locale}.
      * Returns the empty string if this locale does not correspond to a specific
@@ -1798,24 +1868,31 @@
 
         return true;
     }
+    // Android-changed END
 
     /**
      * Returns a name for the locale's variant code that is appropriate for display to the
-     * user.  If possible, the name will be localized for the default locale.  If the locale
+     * user.  If possible, the name will be localized for the default
+     * {@link Locale.Category#DISPLAY DISPLAY} locale.  If the locale
      * doesn't specify a variant code, this function returns the empty string.
+     *
+     * @return The name of the display variant code appropriate to the locale.
      */
     public final String getDisplayVariant() {
         return getDisplayVariant(getDefault(Category.DISPLAY));
     }
 
     /**
-     * Returns the full variant name in the specified {@code Locale} for the variant code
-     * of this {@code Locale}. If there is no matching variant name, the variant code is
-     * returned.
+     * Returns a name for the locale's variant code that is appropriate for display to the
+     * user.  If possible, the name will be localized for inLocale.  If the locale
+     * doesn't specify a variant code, this function returns the empty string.
      *
-     * @since 1.7
+     * @param inLocale The locale for which to retrieve the display variant code.
+     * @return The name of the display variant code appropriate to the given locale.
+     * @exception NullPointerException if <code>inLocale</code> is <code>null</code>
      */
-    public String getDisplayVariant(Locale locale) {
+    // Android-changed BEGIN: Use ICU; added private helper methods.
+    public String getDisplayVariant(Locale inLocale) {
         String variantCode = baseLocale.getVariant();
         if (variantCode.isEmpty()) {
             return "";
@@ -1827,7 +1904,7 @@
             return variantCode;
         }
 
-        String result = ICU.getDisplayVariant(this, locale);
+        String result = ICU.getDisplayVariant(this, inLocale);
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
             result = ICU.getDisplayVariant(this, Locale.getDefault());
         }
@@ -1878,6 +1955,7 @@
 
         return false;
     }
+    // Android-changed END
 
     /**
      * Returns a name for the locale that is appropriate for display to the
@@ -1893,13 +1971,16 @@
      * country<br>
      * </blockquote>
      * depending on which fields are specified in the locale.  If the
-     * language, sacript, country, and variant fields are all empty,
+     * language, script, country, and variant fields are all empty,
      * this function returns the empty string.
+     *
+     * @return The name of the locale appropriate to display.
      */
     public final String getDisplayName() {
         return getDisplayName(getDefault(Category.DISPLAY));
     }
 
+    // Android-changed BEGIN: Use ICU.
     /**
      * Returns this locale's language name, country name, and variant, localized
      * to {@code locale}. The exact output form depends on whether this locale
@@ -1961,17 +2042,19 @@
         }
         return buffer.toString();
     }
+    // Android-changed END
 
     /**
      * Overrides Cloneable.
      */
+    @Override
     public Object clone()
     {
         try {
             Locale that = (Locale)super.clone();
             return that;
         } catch (CloneNotSupportedException e) {
-            throw new InternalError();
+            throw new InternalError(e);
         }
     }
 
@@ -2028,9 +2111,11 @@
      */
     private transient volatile int hashCodeValue = 0;
 
-    private static Locale defaultLocale = null;
-    private static Locale defaultDisplayLocale = null;
-    private static Locale defaultFormatLocale = null;
+    private volatile static Locale defaultLocale = initDefault();
+    private volatile static Locale defaultDisplayLocale = null;
+    private volatile static Locale defaultFormatLocale = null;
+
+    private transient volatile String languageTag;
 
     /**
      * Format a list using given pattern strings.
@@ -2047,9 +2132,11 @@
         // If we have no list patterns, compose the list in a simple,
         // non-localized way.
         if (listPattern == null || listCompositionPattern == null) {
-            StringBuffer result = new StringBuffer();
-            for (int i=0; i<stringList.length; ++i) {
-                if (i>0) result.append(',');
+            StringBuilder result = new StringBuilder();
+            for (int i = 0; i < stringList.length; ++i) {
+                if (i > 0) {
+                    result.append(',');
+                }
                 result.append(stringList[i]);
             }
             return result.toString();
@@ -2096,6 +2183,13 @@
         return composeList(format, newList);
     }
 
+    // Duplicate of sun.util.locale.UnicodeLocaleExtension.isKey in order to
+    // avoid its class loading.
+    private static boolean isUnicodeExtensionKey(String s) {
+        // 2alphanum
+        return (s.length() == 2) && LocaleUtils.isAlphaNumericString(s);
+    }
+
     /**
      * @serialField language    String
      *      language subtag in lower case. (See <a href="java/util/Locale.html#getLanguage()">getLanguage()</a>)
@@ -2157,6 +2251,8 @@
         String variant = (String)fields.get("variant", "");
         String extStr = (String)fields.get("extensions", "");
         baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), script, country, variant);
+        // Android-changed: Handle null for backwards compatible deserialization. http://b/26387905
+        // was: if (extStr.length() > 0) {
         if (extStr != null && extStr.length() > 0) {
             try {
                 InternalLocaleBuilder bldr = new InternalLocaleBuilder();
@@ -2177,7 +2273,7 @@
      * are exactly "ja", "JP", "JP" or "th", "TH", "TH" and script/extensions
      * fields are empty, this method supplies <code>UNICODE_LOCALE_EXTENSION</code>
      * "ca"/"japanese" (calendar type is "japanese") or "nu"/"thai" (number script
-     * type is "thai"). See <a href="Locale.html#special_cases_constructor"/>Special Cases</a>
+     * type is "thai"). See <a href="Locale.html#special_cases_constructor">Special Cases</a>
      * for more information.
      *
      * @return an instance of <code>Locale</code> equivalent to
@@ -2230,9 +2326,9 @@
         return extensions;
     }
 
-    /**
-     * @hide for internal use only.
-     */
+    // Android-removed: Drop nested private class LocaleNameGetter.
+    // Android-added BEGIN: Add 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
@@ -2247,6 +2343,7 @@
 
         return adjusted;
     }
+    // Android-added END
 
     /**
      * Enum for locale categories.  These locale categories are used to get/set
@@ -2584,9 +2681,11 @@
          * @see #setExtension(char, String)
          */
         public Builder removeUnicodeLocaleAttribute(String attribute) {
+            // Android-added BEGIN
             if (attribute == null) {
                 throw new NullPointerException("attribute == null");
             }
+            // Android-added END
 
             try {
                 localeBuilder.removeUnicodeLocaleAttribute(attribute);
diff --git a/ojluni/src/main/java/java/util/ResourceBundle.java b/ojluni/src/main/java/java/util/ResourceBundle.java
index bf73b03..886ffc1 100644
--- a/ojluni/src/main/java/java/util/ResourceBundle.java
+++ b/ojluni/src/main/java/java/util/ResourceBundle.java
@@ -58,7 +58,6 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.jar.JarEntry;
-import java.util.spi.ResourceBundleControlProvider;
 
 import dalvik.system.VMStack;
 import sun.reflect.CallerSensitive;
@@ -66,6 +65,7 @@
 import sun.util.locale.LocaleObjectCache;
 
 
+// Android-changed: Removed reference to ResourceBundleControlProvider.
 /**
  *
  * Resource bundles contain locale-specific objects.  When your program needs a
@@ -205,17 +205,6 @@
  * {@link #getBundle(String, Locale, ClassLoader, Control) getBundle}
  * factory method for details.
  *
- * <p><a name="modify_default_behavior">For the {@code getBundle} factory</a>
- * methods that take no {@link Control} instance, their <a
- * href="#default_behavior"> default behavior</a> of resource bundle loading
- * can be modified with <em>installed</em> {@link
- * ResourceBundleControlProvider} implementations. Any installed providers are
- * detected at the {@code ResourceBundle} class loading time. If any of the
- * providers provides a {@link Control} for the given base name, that {@link
- * Control} will be used instead of the default {@link Control}. If there is
- * more than one service provider installed for supporting the same base name,
- * the first one returned from {@link ServiceLoader} will be used.
- *
  * <h3>Cache Management</h3>
  *
  * Resource bundle instances created by the <code>getBundle</code> factory
@@ -371,6 +360,7 @@
      */
     private volatile Set<String> keySet;
 
+    /* Android-changed: Removed used of ResourceBundleControlProvider.
     private static final List<ResourceBundleControlProvider> providers;
 
     static {
@@ -385,6 +375,7 @@
         }
         providers = list;
     }
+    */
 
     /**
      * Sole constructor.  (For invocation by subclass constructors, typically
@@ -906,19 +897,14 @@
                              control);
     }
 
+    // Android-changed: Removed references to ResourceBundleControlProvider.
     /**
      * Gets a resource bundle using the specified base name, locale, and class
      * loader.
      *
      * <p>This method behaves the same as calling
      * {@link #getBundle(String, Locale, ClassLoader, Control)} passing a
-     * default instance of {@link Control} unless another {@link Control} is
-     * provided with the {@link ResourceBundleControlProvider} SPI. Refer to the
-     * description of <a href="#modify_default_behavior">modifying the default
-     * behavior</a>.
-     *
-     * <p><a name="default_behavior">The following describes the default
-     * behavior</a>.
+     * default instance of {@link Control}.
      *
      * <p><code>getBundle</code> uses the base name, the specified locale, and
      * the default locale (obtained from {@link java.util.Locale#getDefault()
@@ -1314,14 +1300,7 @@
     }
 
     private static Control getDefaultControl(String baseName) {
-        if (providers != null) {
-            for (ResourceBundleControlProvider provider : providers) {
-                Control control = provider.getControl(baseName);
-                if (control != null) {
-                    return control;
-                }
-            }
-        }
+        // Android-changed: Removed used of ResourceBundleControlProvider.
         return Control.INSTANCE;
     }
 
diff --git a/ojluni/src/main/java/java/util/spi/CurrencyNameProvider.java b/ojluni/src/main/java/java/util/spi/CurrencyNameProvider.java
deleted file mode 100644
index a0694bc..0000000
--- a/ojluni/src/main/java/java/util/spi/CurrencyNameProvider.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.spi;
-
-import java.util.Arrays;
-import java.util.Currency;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * An abstract class for service providers that
- * provide localized currency symbols and display names for the
- * {@link java.util.Currency Currency} class.
- * Note that currency symbols are considered names when determining
- * behaviors described in the
- * {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider}
- * specification.
- *
- * @since        1.6
- */
-public abstract class CurrencyNameProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected CurrencyNameProvider() {
-    }
-
-    /**
-     * Gets the symbol of the given currency code for the specified locale.
-     * For example, for "USD" (US Dollar), the symbol is "$" if the specified
-     * locale is the US, while for other locales it may be "US$". If no
-     * symbol can be determined, null should be returned.
-     *
-     * @param currencyCode the ISO 4217 currency code, which
-     *     consists of three upper-case letters between 'A' (U+0041) and
-     *     'Z' (U+005A)
-     * @param locale the desired locale
-     * @return the symbol of the given currency code for the specified locale, or null if
-     *     the symbol is not available for the locale
-     * @exception NullPointerException if <code>currencyCode</code> or
-     *     <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>currencyCode</code> is not in
-     *     the form of three upper-case letters, or <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.util.Currency#getSymbol(java.util.Locale)
-     */
-    public abstract String getSymbol(String currencyCode, Locale locale);
-
-    /**
-     * Returns a name for the currency that is appropriate for display to the
-     * user.  The default implementation returns null.
-     *
-     * @param currencyCode the ISO 4217 currency code, which
-     *     consists of three upper-case letters between 'A' (U+0041) and
-     *     'Z' (U+005A)
-     * @param locale the desired locale
-     * @return the name for the currency that is appropriate for display to the
-     *     user, or null if the name is not available for the locale
-     * @exception IllegalArgumentException if <code>currencyCode</code> is not in
-     *     the form of three upper-case letters, or <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @exception NullPointerException if <code>currencyCode</code> or
-     *     <code>locale</code> is <code>null</code>
-     * @since 1.7
-     */
-    public String getDisplayName(String currencyCode, Locale locale) {
-        if (currencyCode == null || locale == null) {
-            throw new NullPointerException();
-        }
-
-        // Check whether the currencyCode is valid
-        char[] charray = currencyCode.toCharArray();
-        if (charray.length != 3) {
-            throw new IllegalArgumentException("The currencyCode is not in the form of three upper-case letters.");
-        }
-        for (char c : charray) {
-            if (c < 'A' || c > 'Z') {
-                throw new IllegalArgumentException("The currencyCode is not in the form of three upper-case letters.");
-            }
-        }
-
-        // Check whether the locale is valid
-        List<Locale> avail = Arrays.asList(getAvailableLocales());
-        if (!avail.contains(locale)) {
-            throw new IllegalArgumentException("The locale is not available");
-        }
-
-        return null;
-    }
-}
diff --git a/ojluni/src/main/java/java/util/spi/LocaleNameProvider.java b/ojluni/src/main/java/java/util/spi/LocaleNameProvider.java
deleted file mode 100644
index 499aa0d..0000000
--- a/ojluni/src/main/java/java/util/spi/LocaleNameProvider.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * An abstract class for service providers that
- * provide localized names for the
- * {@link java.util.Locale Locale} class.
- *
- * @since        1.6
- */
-public abstract class LocaleNameProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected LocaleNameProvider() {
-    }
-
-    /**
-     * Returns a localized name for the given <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
-     * IETF BCP47</a> language code and the given locale that is appropriate for
-     * display to the user.
-     * For example, if <code>languageCode</code> is "fr" and <code>locale</code>
-     * is en_US, getDisplayLanguage() will return "French"; if <code>languageCode</code>
-     * is "en" and <code>locale</code> is fr_FR, getDisplayLanguage() will return "anglais".
-     * If the name returned cannot be localized according to <code>locale</code>,
-     * (say, the provider does not have a Japanese name for Croatian),
-     * this method returns null.
-     * @param languageCode the language code string in the form of two to eight
-     *     lower-case letters between 'a' (U+0061) and 'z' (U+007A)
-     * @param locale the desired locale
-     * @return the name of the given language code for the specified locale, or null if it's not
-     *     available.
-     * @exception NullPointerException if <code>languageCode</code> or <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>languageCode</code> is not in the form of
-     *     two or three lower-case letters, or <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.util.Locale#getDisplayLanguage(java.util.Locale)
-     */
-    public abstract String getDisplayLanguage(String languageCode, Locale locale);
-
-    /**
-     * Returns a localized name for the given <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
-     * IETF BCP47</a> script code and the given locale that is appropriate for
-     * display to the user.
-     * For example, if <code>scriptCode</code> is "Latn" and <code>locale</code>
-     * is en_US, getDisplayScript() will return "Latin"; if <code>scriptCode</code>
-     * is "Cyrl" and <code>locale</code> is fr_FR, getDisplayScript() will return "cyrillique".
-     * If the name returned cannot be localized according to <code>locale</code>,
-     * (say, the provider does not have a Japanese name for Cyrillic),
-     * this method returns null. The default implementation returns null.
-     * @param scriptCode the four letter script code string in the form of title-case
-     *     letters (the first letter is upper-case character between 'A' (U+0041) and
-     *     'Z' (U+005A) followed by three lower-case character between 'a' (U+0061)
-     *     and 'z' (U+007A)).
-     * @param locale the desired locale
-     * @return the name of the given script code for the specified locale, or null if it's not
-     *     available.
-     * @exception NullPointerException if <code>scriptCode</code> or <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>scriptCode</code> is not in the form of
-     *     four title case letters, or <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.util.Locale#getDisplayScript(java.util.Locale)
-     * @since 1.7
-     */
-    public String getDisplayScript(String scriptCode, Locale locale) {
-        return null;
-    }
-
-    /**
-     * Returns a localized name for the given <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
-     * IETF BCP47</a> region code (either ISO 3166 country code or UN M.49 area
-     * codes) and the given locale that is appropriate for display to the user.
-     * For example, if <code>countryCode</code> is "FR" and <code>locale</code>
-     * is en_US, getDisplayCountry() will return "France"; if <code>countryCode</code>
-     * is "US" and <code>locale</code> is fr_FR, getDisplayCountry() will return "Etats-Unis".
-     * If the name returned cannot be localized according to <code>locale</code>,
-     * (say, the provider does not have a Japanese name for Croatia),
-     * this method returns null.
-     * @param countryCode the country(region) code string in the form of two
-     *     upper-case letters between 'A' (U+0041) and 'Z' (U+005A) or the UN M.49 area code
-     *     in the form of three digit letters between '0' (U+0030) and '9' (U+0039).
-     * @param locale the desired locale
-     * @return the name of the given country code for the specified locale, or null if it's not
-     *     available.
-     * @exception NullPointerException if <code>countryCode</code> or <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>countryCode</code> is not in the form of
-     *     two upper-case letters or three digit letters, or <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.util.Locale#getDisplayCountry(java.util.Locale)
-     */
-    public abstract String getDisplayCountry(String countryCode, Locale locale);
-
-    /**
-     * Returns a localized name for the given variant code and the given locale that
-     * is appropriate for display to the user.
-     * If the name returned cannot be localized according to <code>locale</code>,
-     * this method returns null.
-     * @param variant the variant string
-     * @param locale the desired locale
-     * @return the name of the given variant string for the specified locale, or null if it's not
-     *     available.
-     * @exception NullPointerException if <code>variant</code> or <code>locale</code> is null
-     * @exception IllegalArgumentException if <code>locale</code> isn't
-     *     one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @see java.util.Locale#getDisplayVariant(java.util.Locale)
-     */
-    public abstract String getDisplayVariant(String variant, Locale locale);
-}
diff --git a/ojluni/src/main/java/java/util/spi/LocaleServiceProvider.java b/ojluni/src/main/java/java/util/spi/LocaleServiceProvider.java
deleted file mode 100644
index f2d89c7..0000000
--- a/ojluni/src/main/java/java/util/spi/LocaleServiceProvider.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * <p>
- * This is the super class of all the locale sensitive service provider
- * interfaces (SPIs).
- * <p>
- * Locale sensitive  service provider interfaces are interfaces that
- * correspond to locale sensitive classes in the <code>java.text</code>
- * and <code>java.util</code> packages. The interfaces enable the
- * construction of locale sensitive objects and the retrieval of
- * localized names for these packages. Locale sensitive factory methods
- * and methods for name retrieval in the <code>java.text</code> and
- * <code>java.util</code> packages use implementations of the provider
- * interfaces to offer support for locales beyond the set of locales
- * supported by the Java runtime environment itself.
- * <p>
- * <h4>Packaging of Locale Sensitive Service Provider Implementations</h4>
- * Implementations of these locale sensitive services are packaged using the
- * <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/index.html">Java Extension Mechanism</a>
- * as installed extensions.  A provider identifies itself with a
- * provider-configuration file in the resource directory META-INF/services,
- * using the fully qualified provider interface class name as the file name.
- * The file should contain a list of fully-qualified concrete provider class names,
- * one per line. A line is terminated by any one of a line feed ('\n'), a carriage
- * return ('\r'), or a carriage return followed immediately by a line feed. Space
- * and tab characters surrounding each name, as well as blank lines, are ignored.
- * The comment character is '#' ('\u0023'); on each line all characters following
- * the first comment character are ignored. The file must be encoded in UTF-8.
- * <p>
- * If a particular concrete provider class is named in more than one configuration
- * file, or is named in the same configuration file more than once, then the
- * duplicates will be ignored. The configuration file naming a particular provider
- * need not be in the same jar file or other distribution unit as the provider itself.
- * The provider must be accessible from the same class loader that was initially
- * queried to locate the configuration file; this is not necessarily the class loader
- * that loaded the file.
- * <p>
- * For example, an implementation of the
- * {@link java.text.spi.DateFormatProvider DateFormatProvider} class should
- * take the form of a jar file which contains the file:
- * <pre>
- * META-INF/services/java.text.spi.DateFormatProvider
- * </pre>
- * And the file <code>java.text.spi.DateFormatProvider</code> should have
- * a line such as:
- * <pre>
- * <code>com.foo.DateFormatProviderImpl</code>
- * </pre>
- * which is the fully qualified class name of the class implementing
- * <code>DateFormatProvider</code>.
- * <h4>Invocation of Locale Sensitive Services</h4>
- * <p>
- * Locale sensitive factory methods and methods for name retrieval in the
- * <code>java.text</code> and <code>java.util</code> packages invoke
- * service provider methods when needed to support the requested locale.
- * The methods first check whether the Java runtime environment itself
- * supports the requested locale, and use its support if available.
- * Otherwise, they call the <code>getAvailableLocales()</code> methods of
- * installed providers for the appropriate interface to find one that
- * supports the requested locale. If such a provider is found, its other
- * methods are called to obtain the requested object or name.  When checking
- * whether a locale is supported, the locale's extensions are ignored.
- * If neither the Java runtime environment itself nor an installed provider
- * supports the requested locale, the methods go through a list of candidate
- * locales and repeat the availability check for each until a match is found.
- * The algorithm used for creating a list of candidate locales is same as
- * the one used by <code>ResourceBunlde</code> by default (see
- * {@link java.util.ResourceBundle.Control#getCandidateLocales getCandidateLocales}
- * for the details).  Even if a locale is resolved from the candidate list,
- * methods that return requested objects or names are invoked with the original
- * requested locale including extensions.  The Java runtime environment must
- * support the root locale for all locale sensitive services in order to
- * guarantee that this process terminates.
- * <p>
- * Providers of names (but not providers of other objects) are allowed to
- * return null for some name requests even for locales that they claim to
- * support by including them in their return value for
- * <code>getAvailableLocales</code>. Similarly, the Java runtime
- * environment itself may not have all names for all locales that it
- * supports. This is because the sets of objects for which names are
- * requested can be large and vary over time, so that it's not always
- * feasible to cover them completely. If the Java runtime environment or a
- * provider returns null instead of a name, the lookup will proceed as
- * described above as if the locale was not supported.
- *
- * @since        1.6
- */
-public abstract class LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected LocaleServiceProvider() {
-    }
-
-    /**
-     * Returns an array of all locales for which this locale service provider
-     * can provide localized objects or names.
-     * <p>
-     * <b>Note:</b> Extensions in a <code>Locale</code> are ignored during
-     * service provider lookup.  So the array returned by this method should
-     * not include two or more <code>Locale</code> objects only differing in
-     * their extensions.
-     *
-     * @return An array of all locales for which this locale service provider
-     * can provide localized objects or names.
-     */
-    public abstract Locale[] getAvailableLocales();
-}
diff --git a/ojluni/src/main/java/java/util/spi/ResourceBundleControlProvider.java b/ojluni/src/main/java/java/util/spi/ResourceBundleControlProvider.java
deleted file mode 100644
index e731f0f..0000000
--- a/ojluni/src/main/java/java/util/spi/ResourceBundleControlProvider.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.spi;
-
-import java.util.ResourceBundle;
-
-/**
- * An interface for service providers that provide implementations of {@link
- * java.util.ResourceBundle.Control}. The <a
- * href="../ResourceBundle.html#default_behavior">default resource bundle loading
- * behavior</a> of the {@code ResourceBundle.getBundle} factory methods that take
- * no {@link java.util.ResourceBundle.Control} instance can be modified with {@code
- * ResourceBundleControlProvider} implementations.
- *
- * <p>Provider implementations must be packaged using the <a
- * href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/index.html">Java Extension
- * Mechanism</a> as installed extensions. Refer to {@link java.util.ServiceLoader}
- * for the extension packaging. Any installed {@code
- * ResourceBundleControlProvider} implementations are loaded using {@link
- * java.util.ServiceLoader} at the {@code ResourceBundle} class loading time.
- *
- * @author Masayoshi Okutsu
- * @since 1.8
- * @see ResourceBundle#getBundle(String, java.util.Locale, ClassLoader, ResourceBundle.Control)
- *      ResourceBundle.getBundle
- * @see java.util.ServiceLoader#loadInstalled(Class)
- */
-public interface ResourceBundleControlProvider {
-    /**
-     * Returns a {@code ResourceBundle.Control} instance that is used
-     * to handle resource bundle loading for the given {@code
-     * baseName}. This method must return {@code null} if the given
-     * {@code baseName} isn't handled by this provider.
-     *
-     * @param baseName the base name of the resource bundle
-     * @return a {@code ResourceBundle.Control} instance,
-     *         or {@code null} if the given {@code baseName} is not
-     *         applicable to this provider.
-     * @throws NullPointerException if {@code baseName} is {@code null}
-     */
-    public ResourceBundle.Control getControl(String baseName);
-}
diff --git a/ojluni/src/main/java/java/util/spi/TimeZoneNameProvider.java b/ojluni/src/main/java/java/util/spi/TimeZoneNameProvider.java
deleted file mode 100644
index 730b507..0000000
--- a/ojluni/src/main/java/java/util/spi/TimeZoneNameProvider.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.util.spi;
-
-import java.util.Locale;
-
-/**
- * An abstract class for service providers that
- * provide localized time zone names for the
- * {@link java.util.TimeZone TimeZone} class.
- * The localized time zone names available from the implementations of
- * this class are also the source for the
- * {@link java.text.DateFormatSymbols#getZoneStrings()
- * DateFormatSymbols.getZoneStrings()} method.
- *
- * @since        1.6
- */
-public abstract class TimeZoneNameProvider extends LocaleServiceProvider {
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected TimeZoneNameProvider() {
-    }
-
-    /**
-     * Returns a name for the given time zone ID that's suitable for
-     * presentation to the user in the specified locale. The given time
-     * zone ID is "GMT" or one of the names defined using "Zone" entries
-     * in the "tz database", a public domain time zone database at
-     * <a href="ftp://elsie.nci.nih.gov/pub/">ftp://elsie.nci.nih.gov/pub/</a>.
-     * The data of this database is contained in a file whose name starts with
-     * "tzdata", and the specification of the data format is part of the zic.8
-     * man page, which is contained in a file whose name starts with "tzcode".
-     * <p>
-     * If <code>daylight</code> is true, the method should return a name
-     * appropriate for daylight saving time even if the specified time zone
-     * has not observed daylight saving time in the past.
-     *
-     * @param ID a time zone ID string
-     * @param daylight if true, return the daylight saving name.
-     * @param style either {@link java.util.TimeZone#LONG TimeZone.LONG} or
-     *    {@link java.util.TimeZone#SHORT TimeZone.SHORT}
-     * @param locale the desired locale
-     * @return the human-readable name of the given time zone in the
-     *     given locale, or null if it's not available.
-     * @exception IllegalArgumentException if <code>style</code> is invalid,
-     *     or <code>locale</code> isn't one of the locales returned from
-     *     {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
-     *     getAvailableLocales()}.
-     * @exception NullPointerException if <code>ID</code> or <code>locale</code>
-     *     is null
-     * @see java.util.TimeZone#getDisplayName(boolean, int, java.util.Locale)
-     */
-    public abstract String getDisplayName(String ID, boolean daylight, int style, Locale locale);
-}
diff --git a/ojluni/src/main/java/java/util/spi/package.html b/ojluni/src/main/java/java/util/spi/package.html
deleted file mode 100644
index ce49fb2..0000000
--- a/ojluni/src/main/java/java/util/spi/package.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
-DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
-This code is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 2 only, as
-published by the Free Software Foundation.  Oracle designates this
-particular file as subject to the "Classpath" exception as provided
-by Oracle in the LICENSE file that accompanied this code.
-
-This code is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-version 2 for more details (a copy is included in the LICENSE file that
-accompanied this code).
-
-You should have received a copy of the GNU General Public License version
-2 along with this work; if not, write to the Free Software Foundation,
-Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-or visit www.oracle.com if you need additional information or have any
-questions.
--->
-
-</head>
-<body bgcolor="white">
-Service provider classes for the classes in the java.util package.
-<!--
-<h2>Package Specification</h2>
-
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
-<ul>
-  <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
-</ul>
-
-<h2>Related Documentation</h2>
-
-For overviews, tutorials, examples, guides, and tool documentation, please see:
-<ul>
-  <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
-</ul>
--->
-
-@since 1.6
-</body>
-</html>
diff --git a/ojluni/src/main/java/javax/crypto/CipherSpi.java b/ojluni/src/main/java/javax/crypto/CipherSpi.java
index e563e92..ce72581 100644
--- a/ojluni/src/main/java/javax/crypto/CipherSpi.java
+++ b/ojluni/src/main/java/javax/crypto/CipherSpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,17 +62,17 @@
  * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
  * padding scheme.
  *
- * <p> A transformation is of the form:<p>
+ * <p> A transformation is of the form:
  *
  * <ul>
  * <li>"<i>algorithm/mode/padding</i>" or
- * <p>
+ *
  * <li>"<i>algorithm</i>"
  * </ul>
  *
  * <P> (in the latter case,
  * provider-specific default values for the mode and padding scheme are used).
- * For example, the following is a valid transformation:<p>
+ * For example, the following is a valid transformation:
  *
  * <pre>
  *     Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
@@ -129,7 +129,7 @@
  * <i>DES/CBC/PKCS5Padding</i>, one that implements
  * <i>DES/CFB/PKCS5Padding</i>, and yet another one that implements
  * <i>DES/OFB/PKCS5Padding</i>. That provider would have the following
- * <code>Cipher</code> properties in its master class:<p>
+ * <code>Cipher</code> properties in its master class:
  *
  * <ul>
  *
@@ -160,7 +160,7 @@
  * and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
  * and a generic <i>DES</i> class that subclasses from <code>CipherSpi</code>.
  * That provider would have the following
- * <code>Cipher</code> properties in its master class:<p>
+ * <code>Cipher</code> properties in its master class:
  *
  * <ul>
  *
@@ -197,20 +197,20 @@
  * Check if the provider has registered a subclass of <code>CipherSpi</code>
  * for the specified "<i>algorithm/mode/padding</i>" transformation.
  * <p>If the answer is YES, instantiate it.
- * <p>If the answer is NO, go to the next step.<p>
+ * <p>If the answer is NO, go to the next step.
  * <li>
  * Check if the provider has registered a subclass of <code>CipherSpi</code>
  * for the sub-transformation "<i>algorithm/mode</i>".
  * <p>If the answer is YES, instantiate it, and call
  * <code>engineSetPadding(<i>padding</i>)</code> on the new instance.
- * <p>If the answer is NO, go to the next step.<p>
+ * <p>If the answer is NO, go to the next step.
  * <li>
  * Check if the provider has registered a subclass of <code>CipherSpi</code>
  * for the sub-transformation "<i>algorithm//padding</i>" (note the double
  * slashes).
  * <p>If the answer is YES, instantiate it, and call
  * <code>engineSetMode(<i>mode</i>)</code> on the new instance.
- * <p>If the answer is NO, go to the next step.<p>
+ * <p>If the answer is NO, go to the next step.
  * <li>
  * Check if the provider has registered a subclass of <code>CipherSpi</code>
  * for the sub-transformation "<i>algorithm</i>".
@@ -347,6 +347,9 @@
      * initializing this cipher, or requires
      * algorithm parameters that cannot be
      * determined from the given key.
+     * @throws UnsupportedOperationException if {@code opmode} is
+     * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
+     * by the cipher.
      */
     protected abstract void engineInit(int opmode, Key key,
                                        SecureRandom random)
@@ -399,6 +402,9 @@
      * parameters are inappropriate for this cipher,
      * or if this cipher requires
      * algorithm parameters and <code>params</code> is null.
+     * @throws UnsupportedOperationException if {@code opmode} is
+     * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
+     * by the cipher.
      */
     protected abstract void engineInit(int opmode, Key key,
                                        AlgorithmParameterSpec params,
@@ -452,6 +458,9 @@
      * parameters are inappropriate for this cipher,
      * or if this cipher requires
      * algorithm parameters and <code>params</code> is null.
+     * @throws UnsupportedOperationException if {@code opmode} is
+     * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
+     * by the cipher.
      */
     protected abstract void engineInit(int opmode, Key key,
                                        AlgorithmParameters params,
@@ -777,7 +786,9 @@
             int total = 0;
             do {
                 int chunk = Math.min(inLen, inArray.length);
-                input.get(inArray, 0, chunk);
+                if (chunk > 0) {
+                    input.get(inArray, 0, chunk);
+                }
                 int n;
                 if (isUpdate || (inLen != chunk)) {
                     n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
@@ -805,8 +816,9 @@
             int total = 0;
             boolean resized = false;
             do {
-                int chunk = Math.min(inLen, outSize);
-                if ((a1 == false) && (resized == false)) {
+                int chunk =
+                    Math.min(inLen, (outSize == 0? inArray.length : outSize));
+                if (!a1 && !resized && chunk > 0) {
                     input.get(inArray, 0, chunk);
                     inOfs = 0;
                 }
@@ -820,8 +832,10 @@
                     resized = false;
                     inOfs += chunk;
                     inLen -= chunk;
-                    output.put(outArray, 0, n);
-                    total += n;
+                    if (n > 0) {
+                        output.put(outArray, 0, n);
+                        total += n;
+                    }
                 } catch (ShortBufferException e) {
                     if (resized) {
                         // we just resized the output buffer, but it still
@@ -831,11 +845,13 @@
                     }
                     // output buffer is too small, realloc and try again
                     resized = true;
-                    int newOut = engineGetOutputSize(chunk);
-                    outArray = new byte[newOut];
+                    outSize = engineGetOutputSize(chunk);
+                    outArray = new byte[outSize];
                 }
             } while (inLen > 0);
-            input.position(inLimit);
+            if (a1) {
+                input.position(inLimit);
+            }
             return total;
         }
     }
@@ -863,6 +879,8 @@
      * @exception InvalidKeyException if it is impossible or unsafe to
      * wrap the key with this cipher (e.g., a hardware protected key is
      * being passed to a software-only cipher).
+     *
+     * @throws UnsupportedOperationException if this method is not supported.
      */
     protected byte[] engineWrap(Key key)
         throws IllegalBlockSizeException, InvalidKeyException
@@ -899,6 +917,8 @@
      * @exception InvalidKeyException if <code>wrappedKey</code> does not
      * represent a wrapped key of type <code>wrappedKeyType</code> for
      * the <code>wrappedKeyAlgorithm</code>.
+     *
+     * @throws UnsupportedOperationException if this method is not supported.
      */
     protected Key engineUnwrap(byte[] wrappedKey,
                                String wrappedKeyAlgorithm,
diff --git a/ojluni/src/main/java/sun/nio/fs/LinuxFileSystem.java b/ojluni/src/main/java/sun/nio/fs/LinuxFileSystem.java
index 48f68dc..bdd2f29 100644
--- a/ojluni/src/main/java/sun/nio/fs/LinuxFileSystem.java
+++ b/ojluni/src/main/java/sun/nio/fs/LinuxFileSystem.java
@@ -102,7 +102,9 @@
      */
     @Override
     Iterable<UnixMountEntry> getMountEntries() {
-        return getMountEntries("/etc/mtab");
+        // Android-changed: As /etc/mtab is not available in Android, therefore, using /proc/mounts
+        // instead.
+        return getMountEntries("/proc/mounts");
     }
 
 
diff --git a/ojluni/src/main/java/sun/security/action/PutAllAction.java b/ojluni/src/main/java/sun/security/action/PutAllAction.java
deleted file mode 100644
index b58da23..0000000
--- a/ojluni/src/main/java/sun/security/action/PutAllAction.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.action;
-
-import java.util.Map;
-
-import java.security.Provider;
-import java.security.PrivilegedAction;
-
-/**
- * A convenience PrivilegedAction class for setting the properties of
- * a provider. See the SunRsaSign provider for a usage example.
- *
- * @see sun.security.rsa.SunRsaSign
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-public class PutAllAction implements PrivilegedAction<Void> {
-
-    private final Provider provider;
-    private final Map map;
-
-    public PutAllAction(Provider provider, Map map) {
-        this.provider = provider;
-        this.map = map;
-    }
-
-    public Void run() {
-        provider.putAll(map);
-        return null;
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/util/LocaleServiceProviderPool.java b/ojluni/src/main/java/sun/util/LocaleServiceProviderPool.java
deleted file mode 100644
index cbab860..0000000
--- a/ojluni/src/main/java/sun/util/LocaleServiceProviderPool.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.util;
-
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.IllformedLocaleException;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Locale.Builder;
-import java.util.Map;
-import java.util.ResourceBundle.Control;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.spi.LocaleServiceProvider;
-import libcore.icu.ICU;
-
-import sun.util.logging.PlatformLogger;
-import sun.util.resources.OpenListResourceBundle;
-
-/**
- * An instance of this class holds a set of the third party implementations of a particular
- * locale sensitive service, such as {@link java.util.spi.LocaleNameProvider}.
- *
- */
-public final class LocaleServiceProviderPool {
-
-    /**
-     * A Map that holds singleton instances of this class.  Each instance holds a
-     * set of provider implementations of a particular locale sensitive service.
-     */
-    private static ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProviderPool> poolOfPools =
-        new ConcurrentHashMap<>();
-
-    /**
-     * A Set containing locale service providers that implement the
-     * specified provider SPI
-     */
-    private Set<LocaleServiceProvider> providers =
-        new LinkedHashSet<LocaleServiceProvider>();
-
-    /**
-     * A Map that retains Locale->provider mapping
-     */
-    private Map<Locale, LocaleServiceProvider> providersCache =
-        new ConcurrentHashMap<Locale, LocaleServiceProvider>();
-
-    /**
-     * Available locales for this locale sensitive service.  This also contains
-     * JRE's available locales
-     */
-    private Set<Locale> availableLocales = null;
-
-    /**
-     * Available locales within this JRE.  Currently this is declared as
-     * static.  This could be non-static later, so that they could have
-     * different sets for each locale sensitive services.
-     */
-    private static volatile List<Locale> availableJRELocales = null;
-
-    /**
-     * Provider locales for this locale sensitive service.
-     */
-    private Set<Locale> providerLocales = null;
-
-    /**
-     * Special locale for ja_JP with Japanese calendar
-     */
-    private static Locale locale_ja_JP_JP = new Locale("ja", "JP", "JP");
-
-    /**
-     * Special locale for th_TH with Thai numbering system
-     */
-    private static Locale locale_th_TH_TH = new Locale("th", "TH", "TH");
-
-    /**
-     * A factory method that returns a singleton instance
-     */
-    public static LocaleServiceProviderPool getPool(Class<? extends LocaleServiceProvider> providerClass) {
-        LocaleServiceProviderPool pool = poolOfPools.get(providerClass);
-        if (pool == null) {
-            LocaleServiceProviderPool newPool =
-                new LocaleServiceProviderPool(providerClass);
-            pool = poolOfPools.putIfAbsent(providerClass, newPool);
-            if (pool == null) {
-                pool = newPool;
-            }
-        }
-
-        return pool;
-    }
-
-    /**
-     * The sole constructor.
-     *
-     * @param c class of the locale sensitive service
-     */
-    private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
-        try {
-            AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
-                public Object run() {
-                    for (LocaleServiceProvider provider : ServiceLoader.loadInstalled(c)) {
-                        providers.add(provider);
-                    }
-                    return null;
-                }
-            });
-        }  catch (PrivilegedActionException e) {
-            config(e.toString());
-        }
-    }
-
-    private static void config(String message) {
-        PlatformLogger logger = PlatformLogger.getLogger("sun.util.LocaleServiceProviderPool");
-        logger.config(message);
-    }
-
-    /**
-     * Lazy loaded set of available locales.
-     * Loading all locales is a very long operation.
-     *
-     * We know "providerClasses" contains classes that extends LocaleServiceProvider,
-     * but generic array creation is not allowed, thus the "unchecked" warning
-     * is suppressed here.
-     */
-    private static class AllAvailableLocales {
-        /**
-         * Available locales for all locale sensitive services.
-         * This also contains JRE's available locales
-         */
-        static final Locale[] allAvailableLocales;
-
-        static {
-            @SuppressWarnings("unchecked")
-            Class<LocaleServiceProvider>[] providerClasses =
-                        (Class<LocaleServiceProvider>[]) new Class<?>[] {
-                java.text.spi.BreakIteratorProvider.class,
-                java.text.spi.CollatorProvider.class,
-                java.text.spi.DateFormatProvider.class,
-                java.text.spi.DateFormatSymbolsProvider.class,
-                java.text.spi.DecimalFormatSymbolsProvider.class,
-                java.text.spi.NumberFormatProvider.class,
-                java.util.spi.CurrencyNameProvider.class,
-                java.util.spi.LocaleNameProvider.class,
-                java.util.spi.TimeZoneNameProvider.class,
-            };
-
-            // Normalize locales for look up
-            Locale[] allLocales = ICU.getAvailableLocales();
-            Set<Locale> all = new HashSet<Locale>(allLocales.length);
-            for (Locale locale : allLocales) {
-                all.add(getLookupLocale(locale));
-            }
-
-            for (Class<LocaleServiceProvider> providerClass : providerClasses) {
-                LocaleServiceProviderPool pool =
-                    LocaleServiceProviderPool.getPool(providerClass);
-                all.addAll(pool.getProviderLocales());
-            }
-
-            allAvailableLocales = all.toArray(new Locale[0]);
-        }
-    }
-
-    /**
-     * Returns an array of available locales for all the provider classes.
-     * This array is a merged array of all the locales that are provided by each
-     * provider, including the JRE.
-     *
-     * @return an array of the available locales for all provider classes
-     */
-    public static Locale[] getAllAvailableLocales() {
-        return AllAvailableLocales.allAvailableLocales.clone();
-    }
-
-    /**
-     * Returns an array of available locales.  This array is a
-     * merged array of all the locales that are provided by each
-     * provider, including the JRE.
-     *
-     * @return an array of the available locales
-     */
-    public synchronized Locale[] getAvailableLocales() {
-        if (availableLocales == null) {
-            availableLocales = new HashSet<Locale>(getJRELocales());
-            if (hasProviders()) {
-                availableLocales.addAll(getProviderLocales());
-            }
-        }
-        Locale[] tmp = new Locale[availableLocales.size()];
-        availableLocales.toArray(tmp);
-        return tmp;
-    }
-
-    /**
-     * Returns an array of available locales (already normalized
-     * for service lookup) from providers.
-     * Note that this method does not return a defensive copy.
-     *
-     * @return list of the provider locales
-     */
-    private synchronized Set<Locale> getProviderLocales() {
-        if (providerLocales == null) {
-            providerLocales = new HashSet<Locale>();
-            if (hasProviders()) {
-                for (LocaleServiceProvider lsp : providers) {
-                    Locale[] locales = lsp.getAvailableLocales();
-                    for (Locale locale: locales) {
-                        providerLocales.add(getLookupLocale(locale));
-                    }
-                }
-            }
-        }
-        return providerLocales;
-    }
-
-    /**
-     * Returns whether any provider for this locale sensitive
-     * service is available or not.
-     *
-     * @return true if any provider is available
-     */
-    public boolean hasProviders() {
-        return !providers.isEmpty();
-    }
-
-    /**
-     * Returns an array of available locales (already normalized for
-     * service lookup) supported by the JRE.
-     * Note that this method does not return a defensive copy.
-     *
-     * @return list of the available JRE locales
-     */
-    private List<Locale> getJRELocales() {
-        if (availableJRELocales == null) {
-            synchronized (LocaleServiceProviderPool.class) {
-                if (availableJRELocales == null) {
-                    Locale[] allLocales = ICU.getAvailableLocales();
-                    List<Locale> tmpList = new ArrayList<>(allLocales.length);
-                    for (Locale locale : allLocales) {
-                        tmpList.add(getLookupLocale(locale));
-                    }
-                    availableJRELocales = tmpList;
-                }
-            }
-        }
-        return availableJRELocales;
-    }
-
-    /**
-     * Returns whether the given locale is supported by the JRE.
-     *
-     * @param locale the locale to test.
-     * @return true, if the locale is supported by the JRE. false
-     *     otherwise.
-     */
-    private boolean isJRESupported(Locale locale) {
-        List<Locale> locales = getJRELocales();
-        return locales.contains(getLookupLocale(locale));
-    }
-
-    /**
-     * Returns the provider's localized object for the specified
-     * locale.
-     *
-     * @param getter an object on which getObject() method
-     *     is called to obtain the provider's instance.
-     * @param locale the given locale that is used as the starting one
-     * @param params provider specific parameters
-     * @return provider's instance, or null.
-     */
-    public <P, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
-                                     Locale locale,
-                                     Object... params) {
-        return getLocalizedObjectImpl(getter, locale, true, null, null, null, params);
-    }
-
-    /**
-     * Returns the provider's localized name for the specified
-     * locale.
-     *
-     * @param getter an object on which getObject() method
-     *     is called to obtain the provider's instance.
-     * @param locale the given locale that is used as the starting one
-     * @param bundle JRE resource bundle that contains
-     *     the localized names, or null for localized objects.
-     * @param key the key string if bundle is supplied, otherwise null.
-     * @param params provider specific parameters
-     * @return provider's instance, or null.
-     */
-    public <P, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
-                                     Locale locale,
-                                     OpenListResourceBundle bundle,
-                                     String key,
-                                     Object... params) {
-        return getLocalizedObjectImpl(getter, locale, false, null, bundle, key, params);
-    }
-
-    /**
-     * Returns the provider's localized name for the specified
-     * locale.
-     *
-     * @param getter an object on which getObject() method
-     *     is called to obtain the provider's instance.
-     * @param locale the given locale that is used as the starting one
-     * @param bundleKey JRE specific bundle key. e.g., "USD" is for currency
-           symbol and "usd" is for currency display name in the JRE bundle.
-     * @param bundle JRE resource bundle that contains
-     *     the localized names, or null for localized objects.
-     * @param key the key string if bundle is supplied, otherwise null.
-     * @param params provider specific parameters
-     * @return provider's instance, or null.
-     */
-    public <P, S> S getLocalizedObject(LocalizedObjectGetter<P, S> getter,
-                                     Locale locale,
-                                     String bundleKey,
-                                     OpenListResourceBundle bundle,
-                                     String key,
-                                     Object... params) {
-        return getLocalizedObjectImpl(getter, locale, false, bundleKey, bundle, key, params);
-    }
-
-    private <P, S> S getLocalizedObjectImpl(LocalizedObjectGetter<P, S> getter,
-                                     Locale locale,
-                                     boolean isObjectProvider,
-                                     String bundleKey,
-                                     OpenListResourceBundle bundle,
-                                     String key,
-                                     Object... params) {
-        if (hasProviders()) {
-            if (bundleKey == null) {
-                bundleKey = key;
-            }
-            Locale bundleLocale = (bundle != null ? bundle.getLocale() : null);
-            List<Locale> lookupLocales = getLookupLocales(locale);
-            S providersObj = null;
-
-            // check whether a provider has an implementation that's closer
-            // to the requested locale than the bundle we've found (for
-            // localized names), or Java runtime's supported locale
-            // (for localized objects)
-            Set<Locale> provLoc = getProviderLocales();
-            for (int i = 0; i < lookupLocales.size(); i++) {
-                Locale current = lookupLocales.get(i);
-                if (bundleLocale != null) {
-                    if (current.equals(bundleLocale)) {
-                        break;
-                    }
-                } else {
-                    if (isJRESupported(current)) {
-                        break;
-                    }
-                }
-                if (provLoc.contains(current)) {
-                    // It is safe to assume that findProvider() returns the instance of type P.
-                    @SuppressWarnings("unchecked")
-                    P lsp = (P)findProvider(current);
-                    if (lsp != null) {
-                        providersObj = getter.getObject(lsp, locale, key, params);
-                        if (providersObj != null) {
-                            return providersObj;
-                        } else if (isObjectProvider) {
-                            config(
-                                "A locale sensitive service provider returned null for a localized objects,  which should not happen.  provider: " + lsp + " locale: " + locale);
-                        }
-                    }
-                }
-            }
-
-            // look up the JRE bundle and its parent chain.  Only
-            // providers for localized names are checked hereafter.
-            while (bundle != null) {
-                bundleLocale = bundle.getLocale();
-
-                if (bundle.handleGetKeys().contains(bundleKey)) {
-                    // JRE has it.
-                    return null;
-                } else {
-                    // It is safe to assume that findProvider() returns the instance of type P.
-                    @SuppressWarnings("unchecked")
-                    P lsp = (P)findProvider(bundleLocale);
-                    if (lsp != null) {
-                        providersObj = getter.getObject(lsp, locale, key, params);
-                        if (providersObj != null) {
-                            return providersObj;
-                        }
-                    }
-                }
-
-                // try parent bundle
-                bundle = bundle.getParent();
-            }
-        }
-
-        // not found.
-        return null;
-    }
-
-    /**
-     * Returns a locale service provider instance that supports
-     * the specified locale.
-     *
-     * @param locale the given locale
-     * @return the provider, or null if there is
-     *     no provider available.
-     */
-    private LocaleServiceProvider findProvider(Locale locale) {
-        if (!hasProviders()) {
-            return null;
-        }
-
-        if (providersCache.containsKey(locale)) {
-            LocaleServiceProvider provider = providersCache.get(locale);
-            if (provider != NullProvider.INSTANCE) {
-                return provider;
-            }
-        } else {
-            for (LocaleServiceProvider lsp : providers) {
-                Locale[] locales = lsp.getAvailableLocales();
-                for (Locale available: locales) {
-                    // normalize
-                    available = getLookupLocale(available);
-                    if (locale.equals(available)) {
-                        LocaleServiceProvider providerInCache =
-                            providersCache.put(locale, lsp);
-                        return (providerInCache != null ?
-                                providerInCache :
-                                lsp);
-                    }
-                }
-            }
-            providersCache.put(locale, NullProvider.INSTANCE);
-        }
-        return null;
-    }
-
-    /**
-     * Returns a list of candidate locales for service look up.
-     * @param locale the input locale
-     * @return the list of candiate locales for the given locale
-     */
-    private static List<Locale> getLookupLocales(Locale locale) {
-        // Note: We currently use the default implementation of
-        // ResourceBundle.Control.getCandidateLocales. The result
-        // returned by getCandidateLocales are already normalized
-        // (no extensions) for service look up.
-        List<Locale> lookupLocales = new Control(){}.getCandidateLocales("", locale);
-        return lookupLocales;
-    }
-
-    /**
-     * Returns an instance of Locale used for service look up.
-     * The result Locale has no extensions except for ja_JP_JP
-     * and th_TH_TH
-     *
-     * @param locale the locale
-     * @return the locale used for service look up
-     */
-    private static Locale getLookupLocale(Locale locale) {
-        Locale lookupLocale = locale;
-        Set<Character> extensions = locale.getExtensionKeys();
-        if (!extensions.isEmpty()
-                && !locale.equals(locale_ja_JP_JP)
-                && !locale.equals(locale_th_TH_TH)) {
-            // remove extensions
-            Builder locbld = new Builder();
-            try {
-                locbld.setLocale(locale);
-                locbld.clearExtensions();
-                lookupLocale = locbld.build();
-            } catch (IllformedLocaleException e) {
-                // A Locale with non-empty extensions
-                // should have well-formed fields except
-                // for ja_JP_JP and th_TH_TH. Therefore,
-                // it should never enter in this catch clause.
-                config("A locale(" + locale + ") has non-empty extensions, but has illformed fields.");
-
-                // Fallback - script field will be lost.
-                lookupLocale = new Locale(locale.getLanguage(), locale.getCountry(), locale.getVariant());
-            }
-        }
-        return lookupLocale;
-    }
-
-    /**
-     * A dummy locale service provider that indicates there is no
-     * provider available
-     */
-    private static class NullProvider extends LocaleServiceProvider {
-        private static final NullProvider INSTANCE = new NullProvider();
-
-        public Locale[] getAvailableLocales() {
-            throw new RuntimeException("Should not get called.");
-        }
-    }
-
-    /**
-     * An interface to get a localized object for each locale sensitve
-     * service class.
-     */
-    public interface LocalizedObjectGetter<P, S> {
-        /**
-         * Returns an object from the provider
-         *
-         * @param lsp the provider
-         * @param locale the locale
-         * @param key key string to localize, or null if the provider is not
-         *     a name provider
-         * @param params provider specific params
-         * @return localized object from the provider
-         */
-        public S getObject(P lsp,
-                                Locale locale,
-                                String key,
-                                Object... params);
-    }
-}
diff --git a/ojluni/src/main/java/sun/util/locale/LocaleUtils.java b/ojluni/src/main/java/sun/util/locale/LocaleUtils.java
index 0258e5a..9a89dc0 100644
--- a/ojluni/src/main/java/sun/util/locale/LocaleUtils.java
+++ b/ojluni/src/main/java/sun/util/locale/LocaleUtils.java
@@ -196,7 +196,7 @@
         return isAlpha(c) || isNumeric(c);
     }
 
-    static boolean isAlphaNumericString(String s) {
+    public static boolean isAlphaNumericString(String s) {
         int len = s.length();
         for (int i = 0; i < len; i++) {
             if (!isAlphaNumeric(s.charAt(i))) {
diff --git a/ojluni/src/main/native/IOUtil.c b/ojluni/src/main/native/IOUtil.c
index ea8a3d1..390c0e6 100644
--- a/ojluni/src/main/native/IOUtil.c
+++ b/ojluni/src/main/native/IOUtil.c
@@ -36,14 +36,6 @@
 #include "nio_util.h"
 #include "JNIHelp.h"
 
-// Android-changed: Added missing CHECK_NULL definition.
-#define CHECK_NULL(value) \
-{ \
-    if (value == NULL) { \
-        JNU_ThrowNullPointerException(env, NULL); \
-        return; \
-    } \
-}
 
 #define NATIVE_METHOD(className, functionName, signature) \
 { #functionName, signature, (void*)(className ## _ ## functionName) }
diff --git a/ojluni/src/main/native/Inet4AddressImpl.c b/ojluni/src/main/native/Inet4AddressImpl.c
deleted file mode 100644
index fce6d95..0000000
--- a/ojluni/src/main/native/Inet4AddressImpl.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#ifdef _ALLBSD_SOURCE
-#include <unistd.h>
-#include <sys/param.h>
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
-
-#include "JNIHelp.h"
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-
-//#if defined(__GLIBC__) || (defined(__FreeBSD__) && (__FreeBSD_version >= 601104))
-#define HAS_GLIBC_GETHOSTBY_R   1
-//#endif
-
-#define SET_NONBLOCKING(fd) {           \
-        int flags = fcntl(fd, F_GETFL); \
-        flags |= O_NONBLOCK;            \
-        fcntl(fd, F_SETFL, flags);      \
-}
-
-/**
- * ping implementation.
- * Send a ICMP_ECHO_REQUEST packet every second until either the timeout
- * expires or a answer is received.
- * Returns true is an ECHO_REPLY is received, otherwise, false.
- */
-static jboolean
-ping4(JNIEnv *env, jint fd, struct sockaddr_in* him, jint timeout,
-      struct sockaddr_in* netif, jint ttl) {
-    jint size;
-    jint n, hlen1, icmplen;
-    socklen_t len;
-    char sendbuf[1500];
-    char recvbuf[1500];
-    struct icmp *icmp;
-    struct ip *ip;
-    struct sockaddr_in sa_recv;
-    jchar pid;
-    jint tmout2, seq = 1;
-    struct timeval tv;
-    size_t plen;
-
-    /* icmp_id is a 16 bit data type, therefore down cast the pid */
-    pid = (jchar)getpid();
-    size = 60*1024;
-    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
-    /*
-     * sets the ttl (max number of hops)
-     */
-    if (ttl > 0) {
-      setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
-    }
-    /*
-     * a specific interface was specified, so let's bind the socket
-     * to that interface to ensure the requests are sent only through it.
-     */
-    if (netif != NULL) {
-      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
-        NET_ThrowNew(env, errno, "Can't bind socket");
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-      }
-    }
-    /*
-     * Make the socket non blocking so we can use select
-     */
-    SET_NONBLOCKING(fd);
-    do {
-      /*
-       * create the ICMP request
-       */
-      icmp = (struct icmp *) sendbuf;
-      icmp->icmp_type = ICMP_ECHO;
-      icmp->icmp_code = 0;
-      icmp->icmp_id = htons(pid);
-      icmp->icmp_seq = htons(seq);
-      seq++;
-      gettimeofday(&tv, NULL);
-      memcpy(icmp->icmp_data, &tv, sizeof(tv));
-      plen = ICMP_ADVLENMIN + sizeof(tv);
-      icmp->icmp_cksum = 0;
-      icmp->icmp_cksum = in_cksum((u_short *)icmp, plen);
-      /*
-       * send it
-       */
-      n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him,
-                 sizeof(struct sockaddr));
-      if (n < 0 && errno != EINPROGRESS ) {
-#ifdef __linux__
-        if (errno != EINVAL && errno != EHOSTUNREACH)
-          /*
-           * On some Linux versions, when a socket is bound to the loopback
-           * interface, sendto will fail and errno will be set to
-           * EINVAL or EHOSTUNREACH. When that happens, don't throw an
-           * exception, just return false.
-           */
-#endif /*__linux__ */
-          NET_ThrowNew(env, errno, "Can't send ICMP packet");
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-      }
-
-      tmout2 = timeout > 1000 ? 1000 : timeout;
-      do {
-        tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
-        if (tmout2 >= 0) {
-          len = sizeof(sa_recv);
-          n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&sa_recv, &len);
-          ip = (struct ip*) recvbuf;
-          hlen1 = (ip->ip_hl) << 2;
-          icmp = (struct icmp *) (recvbuf + hlen1);
-          icmplen = n - hlen1;
-          /*
-           * We did receive something, but is it what we were expecting?
-           * I.E.: A ICMP_ECHOREPLY packet with the proper PID.
-           */
-          if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY
-               && (ntohs(icmp->icmp_id) == pid)) {
-            if ((him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
-              untagSocket(env, fd);
-              close(fd);
-              return JNI_TRUE;
-            }
-
-            if (him->sin_addr.s_addr == 0) {
-              untagSocket(env, fd);
-              close(fd);
-              return JNI_TRUE;
-            }
-         }
-
-        }
-      } while (tmout2 > 0);
-      timeout -= 1000;
-    } while (timeout >0);
-    untagSocket(env, fd);
-    close(fd);
-    return JNI_FALSE;
-}
-
-/*
- * Class:     java_net_Inet4AddressImpl
- * Method:    isReachable0
- * Signature: ([bI[bI)Z
- */
-JNIEXPORT jboolean JNICALL
-Inet4AddressImpl_isReachable0(JNIEnv *env, jobject this,
-                                           jbyteArray addrArray,
-                                           jint timeout,
-                                           jbyteArray ifArray,
-                                           jint ttl) {
-    jint addr;
-    jbyte caddr[4];
-    jint fd;
-    struct sockaddr_in him;
-    struct sockaddr_in* netif = NULL;
-    struct sockaddr_in inf;
-    int len = 0;
-    int connect_rv = -1;
-    int sz;
-
-    memset((char *) caddr, 0, sizeof(caddr));
-    memset((char *) &him, 0, sizeof(him));
-    memset((char *) &inf, 0, sizeof(inf));
-    sz = (*env)->GetArrayLength(env, addrArray);
-    if (sz != 4) {
-      return JNI_FALSE;
-    }
-    (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
-    addr = ((caddr[0]<<24) & 0xff000000);
-    addr |= ((caddr[1] <<16) & 0xff0000);
-    addr |= ((caddr[2] <<8) & 0xff00);
-    addr |= (caddr[3] & 0xff);
-    addr = htonl(addr);
-    him.sin_addr.s_addr = addr;
-    him.sin_family = AF_INET;
-    len = sizeof(him);
-    /*
-     * If a network interface was specified, let's create the address
-     * for it.
-     */
-    if (!(IS_NULL(ifArray))) {
-      memset((char *) caddr, 0, sizeof(caddr));
-      (*env)->GetByteArrayRegion(env, ifArray, 0, 4, caddr);
-      addr = ((caddr[0]<<24) & 0xff000000);
-      addr |= ((caddr[1] <<16) & 0xff0000);
-      addr |= ((caddr[2] <<8) & 0xff00);
-      addr |= (caddr[3] & 0xff);
-      addr = htonl(addr);
-      inf.sin_addr.s_addr = addr;
-      inf.sin_family = AF_INET;
-      inf.sin_port = 0;
-      netif = &inf;
-    }
-
-    /*
-     * Let's try to create a RAW socket to send ICMP packets
-     * This usually requires "root" privileges, so it's likely to fail.
-     */
-    fd = JVM_Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
-    if (fd != -1) {
-      /*
-       * It didn't fail, so we can use ICMP_ECHO requests.
-       */
-      tagSocket(env, fd);
-      return ping4(env, fd, &him, timeout, netif, ttl);
-    }
-
-    /*
-     * Can't create a raw socket, so let's try a TCP socket
-     */
-    fd = JVM_Socket(AF_INET, SOCK_STREAM, 0);
-    if (fd == JVM_IO_ERR) {
-        /* note: if you run out of fds, you may not be able to load
-         * the exception class, and get a NoClassDefFoundError
-         * instead.
-         */
-        NET_ThrowNew(env, errno, "Can't create socket");
-        return JNI_FALSE;
-    }
-    tagSocket(env, fd);
-
-    if (ttl > 0) {
-      setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
-    }
-
-    /*
-     * A network interface was specified, so let's bind to it.
-     */
-    if (netif != NULL) {
-      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in)) < 0) {
-        NET_ThrowNew(env, errno, "Can't bind socket");
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-      }
-    }
-
-    /*
-     * Make the socket non blocking so we can use select/poll.
-     */
-    SET_NONBLOCKING(fd);
-
-    /* no need to use NET_Connect as non-blocking */
-    him.sin_port = htons(7);    /* Echo */
-    connect_rv = JVM_Connect(fd, (struct sockaddr *)&him, len);
-
-    /**
-     * connection established or refused immediately, either way it means
-     * we were able to reach the host!
-     */
-    if (connect_rv == 0 || errno == ECONNREFUSED) {
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_TRUE;
-    } else {
-        int optlen;
-
-        switch (errno) {
-        case ENETUNREACH: /* Network Unreachable */
-        case EAFNOSUPPORT: /* Address Family not supported */
-        case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
-#ifdef __linux__
-        case EINVAL:
-        case EHOSTUNREACH:
-          /*
-           * On some Linux versions, when a socket is bound to the loopback
-           * interface, connect will fail and errno will be set to EINVAL
-           * or EHOSTUNREACH.  When that happens, don't throw an exception,
-           * just return false.
-           */
-#endif /* __linux__ */
-          untagSocket(env, fd);
-          close(fd);
-          return JNI_FALSE;
-        }
-
-        if (errno != EINPROGRESS) {
-          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
-                                       "connect failed");
-          untagSocket(env, fd);
-          close(fd);
-          return JNI_FALSE;
-        }
-
-        timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
-        if (timeout >= 0) {
-          /* has connection been established? */
-          optlen = sizeof(connect_rv);
-          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
-                             &optlen) <0) {
-            connect_rv = errno;
-          }
-          if (connect_rv == 0 || connect_rv == ECONNREFUSED) {
-            untagSocket(env, fd);
-            close(fd);
-            return JNI_TRUE;
-          }
-        }
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-    }
-}
diff --git a/ojluni/src/main/native/Inet6AddressImpl.c b/ojluni/src/main/native/Inet6AddressImpl.c
deleted file mode 100644
index 85f2314..0000000
--- a/ojluni/src/main/native/Inet6AddressImpl.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef _ALLBSD_SOURCE
-#include <unistd.h> /* gethostname */
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
-#ifndef IPV6_DEFS_H
-#include <netinet/icmp6.h>
-#endif
-
-#include "java_net_Inet4AddressImpl.h"
-#include "JNIHelp.h"
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-
-/* the initial size of our hostent buffers */
-#ifndef NI_MAXHOST
-#define NI_MAXHOST 1025
-#endif
-
-
-/************************************************************************
- * Inet6AddressImpl
- */
-
-static jclass ni_iacls;
-static jclass ni_ia4cls;
-static jclass ni_ia6cls;
-static jmethodID ni_ia4ctrID;
-static jmethodID ni_ia6ctrID;
-
-/*
- * Class:     java_net_Inet6AddressImpl
- * Method:    getHostByAddr
- * Signature: (I)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL
-Inet6AddressImpl_getHostByAddr0(JNIEnv *env, jobject this,
-                                             jbyteArray addrArray) {
-
-    jstring ret = NULL;
-
-#ifdef AF_INET6
-    char host[NI_MAXHOST+1];
-    int error = 0;
-    int len = 0;
-    jbyte caddr[16];
-
-    if (NET_addrtransAvailable()) {
-        struct sockaddr_in him4;
-        struct sockaddr_in6 him6;
-        struct sockaddr *sa;
-
-        /*
-         * For IPv4 addresses construct a sockaddr_in structure.
-         */
-        if ((*env)->GetArrayLength(env, addrArray) == 4) {
-            jint addr;
-            (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
-            addr = ((caddr[0]<<24) & 0xff000000);
-            addr |= ((caddr[1] <<16) & 0xff0000);
-            addr |= ((caddr[2] <<8) & 0xff00);
-            addr |= (caddr[3] & 0xff);
-            memset((void *) &him4, 0, sizeof(him4));
-            him4.sin_addr.s_addr = (uint32_t) htonl(addr);
-            him4.sin_family = AF_INET;
-            sa = (struct sockaddr *) &him4;
-            len = sizeof(him4);
-        } else {
-            /*
-             * For IPv6 address construct a sockaddr_in6 structure.
-             */
-            (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
-            memset((void *) &him6, 0, sizeof(him6));
-            memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
-            him6.sin6_family = AF_INET6;
-            sa = (struct sockaddr *) &him6 ;
-            len = sizeof(him6) ;
-        }
-
-        error = (*getnameinfo_ptr)(sa, len, host, NI_MAXHOST, NULL, 0,
-                                   NI_NAMEREQD);
-
-        if (!error) {
-            ret = (*env)->NewStringUTF(env, host);
-        }
-    }
-#endif /* AF_INET6 */
-
-    if (ret == NULL) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
-    }
-
-    return ret;
-}
-
-#define SET_NONBLOCKING(fd) {           \
-        int flags = fcntl(fd, F_GETFL); \
-        flags |= O_NONBLOCK;            \
-        fcntl(fd, F_SETFL, flags);      \
-}
-
-#ifdef AF_INET6
-static jboolean
-ping6(JNIEnv *env, jint fd, struct sockaddr_in6* him, jint timeout,
-      struct sockaddr_in6* netif, jint ttl) {
-    jint size;
-    jint n;
-    socklen_t len;
-    char sendbuf[1500];
-    unsigned char recvbuf[1500];
-    struct icmp6_hdr *icmp6;
-    struct sockaddr_in6 sa_recv;
-    jbyte *caddr, *recv_caddr;
-    jchar pid;
-    jint tmout2, seq = 1;
-    struct timeval tv;
-    size_t plen;
-
-#ifdef __linux__
-    {
-    int csum_offset;
-    /**
-     * For some strange reason, the linux kernel won't calculate the
-     * checksum of ICMPv6 packets unless you set this socket option
-     */
-    csum_offset = 2;
-    setsockopt(fd, SOL_RAW, IPV6_CHECKSUM, &csum_offset, sizeof(int));
-    }
-#endif
-
-    caddr = (jbyte *)&(him->sin6_addr);
-
-    /* icmp_id is a 16 bit data type, therefore down cast the pid */
-    pid = (jchar)getpid();
-    size = 60*1024;
-    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
-    if (ttl > 0) {
-      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
-    }
-    if (netif != NULL) {
-      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) <0) {
-        NET_ThrowNew(env, errno, "Can't bind socket");
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-      }
-    }
-    SET_NONBLOCKING(fd);
-
-    do {
-      icmp6 = (struct icmp6_hdr *) sendbuf;
-      icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
-      icmp6->icmp6_code = 0;
-      /* let's tag the ECHO packet with our pid so we can identify it */
-      icmp6->icmp6_id = htons(pid);
-      icmp6->icmp6_seq = htons(seq);
-      seq++;
-      icmp6->icmp6_cksum = 0;
-      gettimeofday(&tv, NULL);
-      memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv));
-      plen = sizeof(struct icmp6_hdr) + sizeof(tv);
-      n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6));
-      if (n < 0 && errno != EINPROGRESS) {
-#ifdef __linux__
-        if (errno != EINVAL && errno != EHOSTUNREACH)
-          /*
-           * On some Linux versions, when a socket is  bound to the
-           * loopback interface, sendto will fail and errno will be
-           * set to EINVAL or EHOSTUNREACH.
-           * When that happens, don't throw an exception, just return false.
-           */
-#endif /*__linux__ */
-        NET_ThrowNew(env, errno, "Can't send ICMP packet");
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-      }
-
-      tmout2 = timeout > 1000 ? 1000 : timeout;
-      do {
-        tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2);
-
-        if (tmout2 >= 0) {
-          len = sizeof(sa_recv);
-          n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &sa_recv, &len);
-          icmp6 = (struct icmp6_hdr *) (recvbuf);
-          recv_caddr = (jbyte *)&(sa_recv.sin6_addr);
-          /*
-           * We did receive something, but is it what we were expecting?
-           * I.E.: An ICMP6_ECHO_REPLY packet with the proper PID and
-           *       from the host that we are trying to determine is reachable.
-           */
-          if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY &&
-              (ntohs(icmp6->icmp6_id) == pid)) {
-            if (NET_IsEqual(caddr, recv_caddr)) {
-              untagSocket(env, fd);
-              close(fd);
-              return JNI_TRUE;
-            }
-            if (NET_IsZeroAddr(caddr)) {
-              untagSocket(env, fd);
-              close(fd);
-              return JNI_TRUE;
-            }
-          }
-        }
-      } while (tmout2 > 0);
-      timeout -= 1000;
-    } while (timeout > 0);
-    untagSocket(env, fd);
-    close(fd);
-    return JNI_FALSE;
-}
-#endif /* AF_INET6 */
-
-/*
- * Class:     java_net_Inet6AddressImpl
- * Method:    isReachable0
- * Signature: ([bII[bI)Z
- */
-JNIEXPORT jboolean JNICALL
-Inet6AddressImpl_isReachable0(JNIEnv *env, jobject this,
-                                           jbyteArray addrArray,
-                                           jint scope,
-                                           jint timeout,
-                                           jbyteArray ifArray,
-                                           jint ttl, jint if_scope) {
-#ifdef AF_INET6
-    jbyte caddr[16];
-    jint fd, sz;
-    struct sockaddr_in6 him6;
-    struct sockaddr_in6 inf6;
-    struct sockaddr_in6* netif = NULL;
-    int len = 0;
-    int connect_rv = -1;
-
-    /*
-     * If IPv6 is not enable, then we can't reach an IPv6 address, can we?
-     */
-    if (!ipv6_available()) {
-      return JNI_FALSE;
-    }
-    /*
-     * If it's an IPv4 address, ICMP won't work with IPv4 mapped address,
-     * therefore, let's delegate to the Inet4Address method.
-     */
-    sz = (*env)->GetArrayLength(env, addrArray);
-    if (sz == 4) {
-      return Inet4AddressImpl_isReachable0(env, this,
-                                                         addrArray,
-                                                         timeout,
-                                                         ifArray, ttl);
-    }
-
-    memset((void *) caddr, 0, 16);
-    memset((void *) &him6, 0, sizeof(him6));
-    (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
-    memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
-    him6.sin6_family = AF_INET6;
-
-    // Android-change: Don't try and figure out a default scope ID if one isn't
-    // set. It's only useful for link local addresses anyway, and callers are
-    // expected to call isReachable with a specific NetworkInterface if they
-    // want to query the reachability of an address that's local to that IF.
-    if (scope > 0)
-      him6.sin6_scope_id = scope;
-    len = sizeof(struct sockaddr_in6);
-    /*
-     * If a network interface was specified, let's create the address
-     * for it.
-     */
-    if (!(IS_NULL(ifArray))) {
-      memset((void *) caddr, 0, 16);
-      memset((void *) &inf6, 0, sizeof(inf6));
-      (*env)->GetByteArrayRegion(env, ifArray, 0, 16, caddr);
-      memcpy((void *)&(inf6.sin6_addr), caddr, sizeof(struct in6_addr) );
-      inf6.sin6_family = AF_INET6;
-      inf6.sin6_scope_id = if_scope;
-      netif = &inf6;
-    }
-    /*
-     * If we can create a RAW socket, then when can use the ICMP ECHO_REQUEST
-     * otherwise we'll try a tcp socket to the Echo port (7).
-     * Note that this is empiric, and not connecting could mean it's blocked
-     * or the echo service has been disabled.
-     */
-
-    fd = JVM_Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-
-    if (fd != -1) { /* Good to go, let's do a ping */
-        tagSocket(env, fd);
-        return ping6(env, fd, &him6, timeout, netif, ttl);
-    }
-
-    /* No good, let's fall back on TCP */
-    fd = JVM_Socket(AF_INET6, SOCK_STREAM, 0);
-    if (fd == JVM_IO_ERR) {
-        /* note: if you run out of fds, you may not be able to load
-         * the exception class, and get a NoClassDefFoundError
-         * instead.
-         */
-        NET_ThrowNew(env, errno, "Can't create socket");
-        return JNI_FALSE;
-    }
-    tagSocket(env, fd);
-
-    if (ttl > 0) {
-      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
-    }
-
-    /*
-     * A network interface was specified, so let's bind to it.
-     */
-    if (netif != NULL) {
-      if (bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) <0) {
-        NET_ThrowNew(env, errno, "Can't bind socket");
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-      }
-    }
-    SET_NONBLOCKING(fd);
-
-    /* no need to use NET_Connect as non-blocking */
-    him6.sin6_port = htons((short) 7); /* Echo port */
-    connect_rv = JVM_Connect(fd, (struct sockaddr *)&him6, len);
-
-    /**
-     * connection established or refused immediately, either way it means
-     * we were able to reach the host!
-     */
-    if (connect_rv == 0 || errno == ECONNREFUSED) {
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_TRUE;
-    } else {
-        int optlen;
-
-        switch (errno) {
-        case ENETUNREACH: /* Network Unreachable */
-        case EAFNOSUPPORT: /* Address Family not supported */
-        case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
-#ifdef __linux__
-        case EINVAL:
-        case EHOSTUNREACH:
-          /*
-           * On some Linuxes, when bound to the loopback interface, connect
-           * loopback interface, connect will fail and errno will
-           * be set to EINVAL or EHOSTUNREACH.  When that happens,
-           * don't throw an exception, just return false.
-           */
-#endif /* __linux__ */
-          untagSocket(env, fd);
-          close(fd);
-          return JNI_FALSE;
-        }
-
-        if (errno != EINPROGRESS) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
-                                         "connect failed");
-            untagSocket(env, fd);
-            close(fd);
-            return JNI_FALSE;
-        }
-
-        timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
-
-        if (timeout >= 0) {
-          /* has connection been established */
-          optlen = sizeof(connect_rv);
-          if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
-                             &optlen) <0) {
-            connect_rv = errno;
-          }
-          if (connect_rv == 0 || ECONNREFUSED) {
-            untagSocket(env, fd);
-            close(fd);
-            return JNI_TRUE;
-          }
-        }
-        untagSocket(env, fd);
-        close(fd);
-        return JNI_FALSE;
-    }
-#else /* AF_INET6 */
-    return JNI_FALSE;
-#endif /* AF_INET6 */
-}
-
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(Inet6AddressImpl, isReachable0, "([BII[BII)Z"),
-  NATIVE_METHOD(Inet6AddressImpl, getHostByAddr0, "([B)Ljava/lang/String;"),
-};
-
-void register_java_net_Inet6AddressImpl(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/net/Inet6AddressImpl", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/ObjectInputStream.c b/ojluni/src/main/native/ObjectInputStream.c
index 55cebba..95eeec4 100644
--- a/ojluni/src/main/native/ObjectInputStream.c
+++ b/ojluni/src/main/native/ObjectInputStream.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/native/ObjectOutputStream.c b/ojluni/src/main/native/ObjectOutputStream.c
index d74e31f..25ee3bf 100644
--- a/ojluni/src/main/native/ObjectOutputStream.c
+++ b/ojluni/src/main/native/ObjectOutputStream.c
@@ -192,4 +192,3 @@
 void register_java_io_ObjectOutputStream(JNIEnv* env) {
     jniRegisterNativeMethods(env, "java/io/ObjectOutputStream", gMethods, NELEM(gMethods));
 }
-
diff --git a/ojluni/src/main/native/Register.cpp b/ojluni/src/main/native/Register.cpp
index 0d31d02..c7d3ce1 100644
--- a/ojluni/src/main/native/Register.cpp
+++ b/ojluni/src/main/native/Register.cpp
@@ -25,12 +25,13 @@
 
 #define LOG_TAG "libcore" // We'll be next to "dalvikvm" in the log; make the distinction clear.
 
-#include "cutils/log.h"
+#include <stdlib.h>
+
+#include <android/log.h>
+
 #include "JniConstants.h"
 #include "ScopedLocalFrame.h"
 
-#include <stdlib.h>
-
 extern "C" {
 
 extern void register_java_io_Console(JNIEnv* env);
@@ -54,7 +55,6 @@
 extern void register_java_net_DatagramPacket(JNIEnv*);
 extern void register_java_net_Inet4Address(JNIEnv*);
 extern void register_java_net_Inet6Address(JNIEnv*);
-extern void register_java_net_Inet6AddressImpl(JNIEnv*);
 extern void register_java_net_InetAddress(JNIEnv*);
 extern void register_java_net_PlainDatagramSocketImpl(JNIEnv*);
 extern void register_java_net_PlainSocketImpl(JNIEnv*);
@@ -131,7 +131,6 @@
     register_java_net_PlainSocketImpl(env);
     register_java_net_PlainDatagramSocketImpl(env);
     register_java_net_DatagramPacket(env);
-    register_java_net_Inet6AddressImpl(env);
     register_java_net_SocketInputStream(env);
     register_java_net_SocketOutputStream(env);
     register_java_nio_Bits(env);
diff --git a/ojluni/src/main/native/System.c b/ojluni/src/main/native/System.c
index 4c547c0..863a8c5 100644
--- a/ojluni/src/main/native/System.c
+++ b/ojluni/src/main/native/System.c
@@ -22,19 +22,22 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#include <string.h>
-#include <stdlib.h>
+#define LOG_TAG "libcore"
 
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <android/log.h>
+
+#include "io_util.h"
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
-#include "io_util.h"
-
 
 #include "openssl/opensslv.h"
 #include "zlib.h"
 #include "JNIHelp.h"
-#include "cutils/log.h"
 #if defined(__ANDROID__)
 void android_get_LD_LIBRARY_PATH(char*, size_t);
 #endif
diff --git a/ojluni/src/main/native/UnixFileSystem_md.c b/ojluni/src/main/native/UnixFileSystem_md.c
index ebed636..61f907c 100644
--- a/ojluni/src/main/native/UnixFileSystem_md.c
+++ b/ojluni/src/main/native/UnixFileSystem_md.c
@@ -82,7 +82,7 @@
 
     WITH_PLATFORM_STRING(env, pathname, path) {
         char canonicalPath[JVM_MAXPATHLEN];
-        if (canonicalize(JVM_NativePath((char *)path),
+        if (canonicalize((char *)path,
                          canonicalPath, JVM_MAXPATHLEN) < 0) {
             JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
         } else {
@@ -133,6 +133,7 @@
     return rv;
 }
 
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_checkAccess0(JNIEnv *env, jobject this,
                                          jobject file, jint a)
@@ -140,6 +141,7 @@
     jboolean rv = JNI_FALSE;
     int mode = 0;
     switch (a) {
+    // Android-changed: Added ACCESS_OK case
     case java_io_FileSystem_ACCESS_OK:
         mode = F_OK;
         break;
@@ -162,7 +164,7 @@
     return rv;
 }
 
-
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_setPermission0(JNIEnv *env, jobject this,
                                            jobject file,
@@ -210,6 +212,7 @@
     return rv;
 }
 
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jlong JNICALL
 Java_java_io_UnixFileSystem_getLastModifiedTime0(JNIEnv *env, jobject this,
                                                  jobject file)
@@ -225,7 +228,7 @@
     return rv;
 }
 
-
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jlong JNICALL
 Java_java_io_UnixFileSystem_getLength0(JNIEnv *env, jobject this,
                                        jobject file)
@@ -244,7 +247,7 @@
 
 /* -- File operations -- */
 
-
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_createFileExclusively0(JNIEnv *env, jclass cls,
                                                    jstring pathname)
@@ -252,19 +255,18 @@
     jboolean rv = JNI_FALSE;
 
     WITH_PLATFORM_STRING(env, pathname, path) {
-        int fd;
-        if (!strcmp (path, "/")) {
-            fd = JVM_EEXIST;    /* The root directory always exists */
-        } else {
-            fd = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666);
-        }
-        if (fd < 0) {
-            if (fd != JVM_EEXIST) {
-                JNU_ThrowIOExceptionWithLastError(env, path);
+        FD fd;
+        /* The root directory always exists */
+        if (strcmp (path, "/")) {
+            fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666);
+            if (fd < 0) {
+                if (errno != EEXIST)
+                    JNU_ThrowIOExceptionWithLastError(env, path);
+            } else {
+                if (close(fd) == -1)
+                    JNU_ThrowIOExceptionWithLastError(env, path);
+                rv = JNI_TRUE;
             }
-        } else {
-            JVM_Close(fd);
-            rv = JNI_TRUE;
         }
     } END_PLATFORM_STRING(env, path);
     return rv;
@@ -285,7 +287,7 @@
     return rv;
 }
 
-
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jobjectArray JNICALL
 Java_java_io_UnixFileSystem_list0(JNIEnv *env, jobject this,
                                   jobject file)
@@ -295,6 +297,11 @@
     struct dirent64 *result;
     int len, maxlen;
     jobjectArray rv, old;
+    jclass str_class;
+
+    str_class = JNU_ClassString(env);
+    CHECK_NULL_RETURN(str_class, NULL);
+
 
     WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path) {
         dir = opendir(path);
@@ -311,7 +318,7 @@
     /* Allocate an initial String array */
     len = 0;
     maxlen = 16;
-    rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
+    rv = (*env)->NewObjectArray(env, maxlen, str_class, NULL);
     if (rv == NULL) goto error;
 
     /* Scan the directory */
@@ -321,8 +328,7 @@
             continue;
         if (len == maxlen) {
             old = rv;
-            rv = (*env)->NewObjectArray(env, maxlen <<= 1,
-                                        JNU_ClassString(env), NULL);
+            rv = (*env)->NewObjectArray(env, maxlen <<= 1, str_class, NULL);
             if (rv == NULL) goto error;
             if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
             (*env)->DeleteLocalRef(env, old);
@@ -341,7 +347,7 @@
 
     /* Copy the final results into an appropriately-sized array */
     old = rv;
-    rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL);
+    rv = (*env)->NewObjectArray(env, len, str_class, NULL);
     if (rv == NULL) {
         return NULL;
     }
@@ -356,7 +362,7 @@
     return NULL;
 }
 
-
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_createDirectory0(JNIEnv *env, jobject this,
                                              jobject file)
@@ -388,6 +394,7 @@
     return rv;
 }
 
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_setLastModifiedTime0(JNIEnv *env, jobject this,
                                                  jobject file, jlong time)
@@ -416,7 +423,7 @@
     return rv;
 }
 
-
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jboolean JNICALL
 Java_java_io_UnixFileSystem_setReadOnly0(JNIEnv *env, jobject this,
                                          jobject file)
@@ -434,6 +441,7 @@
     return rv;
 }
 
+// Android-changed: Name changed because of added thread policy check
 JNIEXPORT jlong JNICALL
 Java_java_io_UnixFileSystem_getSpace0(JNIEnv *env, jobject this,
                                       jobject file, jint t)
diff --git a/ojluni/src/main/native/canonicalize_md.c b/ojluni/src/main/native/canonicalize_md.c
index 8fdacc9..832cae3 100644
--- a/ojluni/src/main/native/canonicalize_md.c
+++ b/ojluni/src/main/native/canonicalize_md.c
@@ -233,6 +233,7 @@
                 /* The subpath has a canonical path */
                 break;
             }
+            // Android-changed: Added ENOTCONN case (b/26645585, b/26070583)
             else if (errno == ENOENT || errno == ENOTDIR || errno == EACCES || errno == ENOTCONN) {
                 /* If the lookup of a particular subpath fails because the file
                    does not exist, because it is of the wrong type, or because
diff --git a/ojluni/src/main/native/io_util_md.c b/ojluni/src/main/native/io_util_md.c
index 430e983..8b8a687 100644
--- a/ojluni/src/main/native/io_util_md.c
+++ b/ojluni/src/main/native/io_util_md.c
@@ -62,6 +62,29 @@
 }
 #endif
 
+FD
+handleOpen(const char *path, int oflag, int mode) {
+    FD fd;
+    RESTARTABLE(open64(path, oflag, mode), fd);
+    if (fd != -1) {
+        struct stat64 buf64;
+        int result;
+        RESTARTABLE(fstat64(fd, &buf64), result);
+        if (result != -1) {
+            if (S_ISDIR(buf64.st_mode)) {
+                close(fd);
+                errno = EISDIR;
+                fd = -1;
+            }
+        } else {
+            close(fd);
+            fd = -1;
+        }
+    }
+    return fd;
+}
+
+
 void
 fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
 {
@@ -74,26 +97,12 @@
         while ((p > ps) && (*p == '/'))
             *p-- = '\0';
 #endif
-        fd = JVM_Open(ps, flags, 0666);
-        if (fd >= 0) {
-            // BEGIN android
-            // Posix open(2) fails with EISDIR only if you ask for write permission.
-            // Java disallows reading directories too.
-            struct stat stat;
-            fstat(fd, &stat);
-
-            if (S_ISDIR(stat.st_mode)) {
-              close(fd);
-              errno = EISDIR; // For Exception message
-              throwFileNotFoundException(env, path);
-            } else {
-              // END android
-              SET_FD(this, fd, fid);
-            }
+        fd = handleOpen(ps, flags, 0666);
+        if (fd != -1) {
+            SET_FD(this, fd, fid);
         } else {
             throwFileNotFoundException(env, path);
         }
-
     } END_PLATFORM_STRING(env, ps);
 }
 
diff --git a/ojluni/src/main/native/io_util_md.h b/ojluni/src/main/native/io_util_md.h
index ca7ab43..d2ceffc 100644
--- a/ojluni/src/main/native/io_util_md.h
+++ b/ojluni/src/main/native/io_util_md.h
@@ -32,6 +32,13 @@
 #define FD jint
 
 /*
+ * Prototypes for functions in io_util_md.c called from io_util.c,
+ * FileDescriptor.c, FileInputStream.c, FileOutputStream.c,
+ * UnixFileSystem_md.c
+ */
+FD handleOpen(const char *path, int oflag, int mode);
+
+/*
  * Macros to set/get fd from the java.io.FileDescriptor.  These
  * macros rely on having an appropriately defined 'this' object
  * within the scope in which they're used.
@@ -68,6 +75,15 @@
 #define SET_HANDLE(fd) return (jlong)-1
 
 /*
+ * Retry the operation if it is interrupted
+ */
+#define RESTARTABLE(_cmd, _result) do { \
+    do { \
+        _result = _cmd; \
+    } while((_result == -1) && (errno == EINTR)); \
+} while(0)
+
+/*
  * IO helper function(s)
  */
 void fileClose(JNIEnv *env, jobject this, jfieldID fid);
diff --git a/ojluni/src/main/native/java_net_Inet4AddressImpl.h b/ojluni/src/main/native/java_net_Inet4AddressImpl.h
deleted file mode 100644
index 8ee8820..0000000
--- a/ojluni/src/main/native/java_net_Inet4AddressImpl.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This file was generated from java/net/Inet4AddressImpl.java and
- * is licensed under the same terms.  The copyright and license information
- * for java/net/Inet4AddressImpl.java follows.
- *
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class java_net_Inet4AddressImpl */
-
-#ifndef _Included_java_net_Inet4AddressImpl
-#define _Included_java_net_Inet4AddressImpl
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     java_net_Inet4AddressImpl
- * Method:    getLocalHostName
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Inet4AddressImpl_getLocalHostName
-  (JNIEnv *, jobject);
-
-/*
- * Class:     java_net_Inet4AddressImpl
- * Method:    lookupAllHostAddr
- * Signature: (Ljava/lang/String;)[Ljava/net/InetAddress;
- */
-JNIEXPORT jobjectArray JNICALL Inet4AddressImpl_lookupAllHostAddr
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     java_net_Inet4AddressImpl
- * Method:    getHostByAddr
- * Signature: ([B)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Inet4AddressImpl_getHostByAddr
-  (JNIEnv *, jobject, jbyteArray);
-
-/*
- * Class:     java_net_Inet4AddressImpl
- * Method:    isReachable0
- * Signature: ([BI[BI)Z
- */
-JNIEXPORT jboolean JNICALL Inet4AddressImpl_isReachable0
-  (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/ojluni/src/main/native/jni_util.h b/ojluni/src/main/native/jni_util.h
index f82b5fd..d9f3848 100644
--- a/ojluni/src/main/native/jni_util.h
+++ b/ojluni/src/main/native/jni_util.h
@@ -278,6 +278,25 @@
 #define IS_NULL(obj) ((obj) == NULL)
 #define JNU_IsNull(env,obj) ((obj) == NULL)
 
+/************************************************************************
+ * Miscellaneous utilities used by the class libraries to return from
+ * a function if a value is NULL or an exception is pending.
+ */
+
+#define CHECK_NULL(x)                           \
+    do {                                        \
+        if ((x) == NULL) {                      \
+            return;                             \
+        }                                       \
+    } while (0)                                 \
+
+#define CHECK_NULL_RETURN(x, y)                 \
+    do {                                        \
+        if ((x) == NULL) {                      \
+            return (y);                         \
+        }                                       \
+    } while (0)                                 \
+
 
 /************************************************************************
  * Debugging utilities
diff --git a/ojluni/src/main/native/net_util.h b/ojluni/src/main/native/net_util.h
index 8888877..4b7310b 100644
--- a/ojluni/src/main/native/net_util.h
+++ b/ojluni/src/main/native/net_util.h
@@ -42,9 +42,6 @@
 #define NET_ERROR(env, ex, msg) \
 { if (!(*env)->ExceptionOccurred(env)) JNU_ThrowByName(env, ex, msg); }
 
-#define CHECK_NULL(x) if ((x) == NULL) return;
-#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
-
 /************************************************************************
  * Cached field IDs
  *
diff --git a/ojluni/src/main/native/openjdksub.mk b/ojluni/src/main/native/openjdksub.mk
index 3a3fcb0..c68b01c 100644
--- a/ojluni/src/main/native/openjdksub.mk
+++ b/ojluni/src/main/native/openjdksub.mk
@@ -1,4 +1,4 @@
-\# -*- mode: makefile -*-
+# -*- mode: makefile -*-
 # This file is included by the top-level libcore Android.mk.
 # It's not a normal makefile, so we don't include CLEAR_VARS
 # or BUILD_*_LIBRARY.
@@ -54,8 +54,6 @@
     PlainSocketImpl.c \
     PlainDatagramSocketImpl.c \
     DatagramPacket.c \
-    Inet4AddressImpl.c \
-    Inet6AddressImpl.c \
     ServerSocketChannelImpl.c \
     SocketInputStream.c \
     SocketOutputStream.c \
diff --git a/ojluni/src/main/native/sun_nio_fs_LinuxNativeDispatcher.h b/ojluni/src/main/native/sun_nio_fs_LinuxNativeDispatcher.h
index 6accb11..5295d4a 100644
--- a/ojluni/src/main/native/sun_nio_fs_LinuxNativeDispatcher.h
+++ b/ojluni/src/main/native/sun_nio_fs_LinuxNativeDispatcher.h
@@ -14,9 +14,6 @@
 #undef sun_nio_fs_LinuxNativeDispatcher_SUPPORTS_BIRTHTIME
 #define sun_nio_fs_LinuxNativeDispatcher_SUPPORTS_BIRTHTIME 65536L
 
-#define CHECK_NULL(x) if ((x) == NULL) return;
-#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
-
 /*
  * Class:     sun_nio_fs_LinuxNativeDispatcher
  * Method:    setmntent0
diff --git a/ojluni/src/main/native/sun_nio_fs_UnixNativeDispatcher.h b/ojluni/src/main/native/sun_nio_fs_UnixNativeDispatcher.h
index d67dfb9..efeba3e 100644
--- a/ojluni/src/main/native/sun_nio_fs_UnixNativeDispatcher.h
+++ b/ojluni/src/main/native/sun_nio_fs_UnixNativeDispatcher.h
@@ -14,9 +14,6 @@
 #undef sun_nio_fs_UnixNativeDispatcher_SUPPORTS_BIRTHTIME
 #define sun_nio_fs_UnixNativeDispatcher_SUPPORTS_BIRTHTIME 65536L
 
-#define CHECK_NULL(x) if ((x) == NULL) return;
-#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
-
 /*
  * Class:     sun_nio_fs_UnixNativeDispatcher
  * Method:    getcwd
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index c8cfc95..c3d2b17 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1172,17 +1172,6 @@
     ojluni/src/main/java/java/lang/invoke/MethodTypeForm.java \
     ojluni/src/main/java/java/lang/invoke/Stable.java \
     ojluni/src/main/java/java/lang/invoke/WrongMethodTypeException.java \
-    ojluni/src/main/java/java/text/spi/BreakIteratorProvider.java \
-    ojluni/src/main/java/java/text/spi/CollatorProvider.java \
-    ojluni/src/main/java/java/text/spi/DateFormatProvider.java \
-    ojluni/src/main/java/java/text/spi/DateFormatSymbolsProvider.java \
-    ojluni/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java \
-    ojluni/src/main/java/java/text/spi/NumberFormatProvider.java \
-    ojluni/src/main/java/java/util/spi/CurrencyNameProvider.java \
-    ojluni/src/main/java/java/util/spi/LocaleNameProvider.java \
-    ojluni/src/main/java/java/util/spi/LocaleServiceProvider.java \
-    ojluni/src/main/java/java/util/spi/ResourceBundleControlProvider.java \
-    ojluni/src/main/java/java/util/spi/TimeZoneNameProvider.java \
     ojluni/src/main/java/jdk/net/ExtendedSocketOptions.java \
     ojluni/src/main/java/jdk/net/NetworkPermission.java \
     ojluni/src/main/java/jdk/net/SocketFlow.java \
@@ -1432,7 +1421,6 @@
     ojluni/src/main/java/sun/security/action/GetIntegerAction.java \
     ojluni/src/main/java/sun/security/action/GetPropertyAction.java \
     ojluni/src/main/java/sun/security/action/LoadLibraryAction.java \
-    ojluni/src/main/java/sun/security/action/PutAllAction.java \
     ojluni/src/main/java/sun/security/jca/GetInstance.java \
     ojluni/src/main/java/sun/security/jca/JCAUtil.java \
     ojluni/src/main/java/sun/security/jca/ProviderConfig.java \
@@ -1599,7 +1587,6 @@
     ojluni/src/main/java/sun/util/locale/LocaleSyntaxException.java \
     ojluni/src/main/java/sun/util/locale/LocaleUtils.java \
     ojluni/src/main/java/sun/util/locale/ParseStatus.java \
-    ojluni/src/main/java/sun/util/LocaleServiceProviderPool.java \
     ojluni/src/main/java/sun/util/locale/StringTokenIterator.java \
     ojluni/src/main/java/sun/util/locale/UnicodeLocaleExtension.java \
     ojluni/src/main/java/sun/util/logging/LoggingProxy.java \
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 1f6756e..42faad7 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -222,6 +222,10 @@
         provide("Mac", "HmacSHA256");
         provide("Mac", "HmacSHA384");
         provide("Mac", "HmacSHA512");
+        provide("Mac", "PBEWITHHMACSHA224");
+        provide("Mac", "PBEWITHHMACSHA256");
+        provide("Mac", "PBEWITHHMACSHA384");
+        provide("Mac", "PBEWITHHMACSHA512");
         // If adding a new MessageDigest, consider adding it to JarVerifier
         provide("MessageDigest", "MD2");
         provide("MessageDigest", "MD5");
@@ -244,6 +248,10 @@
         provide("SecretKeyFactory", "PBEWithSHA1AndDESede");
         provide("SecretKeyFactory", "PBEWithSHA1AndRC2_40");
         provide("SecretKeyFactory", "PBKDF2WithHmacSHA1");
+        provide("SecretKeyFactory", "PBKDF2WithHmacSHA224");
+        provide("SecretKeyFactory", "PBKDF2WithHmacSHA256");
+        provide("SecretKeyFactory", "PBKDF2WithHmacSHA384");
+        provide("SecretKeyFactory", "PBKDF2WithHmacSHA512");
         provide("SecretKeyFactory", "PBKDF2WithHmacSHA1And8bit");
         provide("SecureRandom", "SHA1PRNG");
         provide("Signature", "MD2withRSA");
diff --git a/support/src/test/java/libcore/tlswire/handshake/ClientHello.java b/support/src/test/java/libcore/tlswire/handshake/ClientHello.java
index ec88662..dd42cb1 100644
--- a/support/src/test/java/libcore/tlswire/handshake/ClientHello.java
+++ b/support/src/test/java/libcore/tlswire/handshake/ClientHello.java
@@ -18,12 +18,12 @@
 
 import libcore.tlswire.util.TlsProtocolVersion;
 import libcore.tlswire.util.IoUtils;
-import libcore.util.HexEncoding;
 import java.io.ByteArrayInputStream;
 import java.io.DataInput;
 import java.io.DataInputStream;
 import java.io.EOFException;
 import java.io.IOException;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -98,8 +98,8 @@
     @Override
     public String toString() {
         return "ClientHello{client version: " + clientVersion
-                + ", random: " + new String(HexEncoding.encode(random))
-                + ", sessionId: " + new String(HexEncoding.encode(sessionId))
+                + ", random: " + new BigInteger(1, random).toString(16)
+                + ", sessionId: " + new BigInteger(1, sessionId).toString(16)
                 + ", cipher suites: " + cipherSuites
                 + ", compression methods: " + compressionMethods
                 + ((extensions != null) ? (", extensions: " + String.valueOf(extensions)) : "")
diff --git a/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java b/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
index 2a77687..567c082 100644
--- a/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
+++ b/support/src/test/java/libcore/tlswire/handshake/HelloExtension.java
@@ -17,9 +17,9 @@
 package libcore.tlswire.handshake;
 
 import libcore.tlswire.util.IoUtils;
-import libcore.util.HexEncoding;
 import java.io.DataInput;
 import java.io.IOException;
+import java.math.BigInteger;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -100,6 +100,7 @@
 
     @Override
     public String toString() {
-        return "HelloExtension{type: " + name + ", data: " + HexEncoding.encode(data) + "}";
+        return "HelloExtension{type: " + name + ", data: " + new BigInteger(1, data).toString(16)
+            + "}";
     }
 }
diff --git a/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java b/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java
index 6ca6177..b0efb91d 100644
--- a/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java
+++ b/support/src/test/java/org/apache/harmony/xnet/tests/support/mySSLSession.java
@@ -63,7 +63,7 @@
     }
 
     public long getCreationTime() {
-        return 1000l;
+        return 1000L;
     }
 
     public byte[] getId() {
@@ -71,7 +71,7 @@
     }
 
     public long getLastAccessedTime() {
-        return 2000l;
+        return 2000L;
     }
 
     public Certificate[] getLocalCertificates() {
diff --git a/support/src/test/java/tests/support/Support_ClassLoader.java b/support/src/test/java/tests/support/Support_ClassLoader.java
index 3ba1d7e..1c372d4 100644
--- a/support/src/test/java/tests/support/Support_ClassLoader.java
+++ b/support/src/test/java/tests/support/Support_ClassLoader.java
@@ -19,8 +19,6 @@
 import java.net.URL;
 import java.net.URLClassLoader;
 
-import dalvik.system.DexClassLoader;
-
 /**
  * Support class for creating a file-based ClassLoader. Delegates to either
  * Dalvik's PathClassLoader or the RI's URLClassLoader, but does so by-name.
@@ -34,12 +32,13 @@
         try {
             Support_ClassLoader factory;
 
+            String packageName = Support_ClassLoader.class.getPackage().getName();
             if ("Dalvik".equals(System.getProperty("java.vm.name"))) {
                 factory = (Support_ClassLoader)Class.forName(
-                    "tests.support.Support_ClassLoader$Dalvik").newInstance();
+                    packageName + ".Support_ClassLoaderDalvik").newInstance();
             } else {
                 factory = (Support_ClassLoader)Class.forName(
-                    "tests.support.Support_ClassLoader$RefImpl").newInstance();
+                    packageName + ".Support_ClassLoader$RefImpl").newInstance();
             }
 
             return factory.getClassLoader(url, parent);
@@ -49,29 +48,6 @@
     }
 
     /**
-     * Implementation for Dalvik. Uses the DexClassLoader, so we can write
-     * temporary DEX files to a special directory. We don't want to spoil the
-     * system's DEX cache with our files. Also, we might not have write access
-     * to the system's DEX cache at all (which is the case when we're running
-     * CTS).
-     */
-    static class Dalvik extends Support_ClassLoader {
-
-        private static File tmp;
-
-        static {
-            tmp = new File(System.getProperty("java.io.tmpdir"), "dex-cache");
-            tmp.mkdirs();
-        }
-
-        @Override
-        public ClassLoader getClassLoader(URL url, ClassLoader parent) {
-            return new DexClassLoader(url.getPath(), tmp.getAbsolutePath(),
-                    null, parent);
-        }
-    }
-
-    /**
      * Implementation for the reference implementation. Nothing interesting to
      * see here. Please get along.
      */
diff --git a/support/src/test/java/tests/support/Support_ClassLoaderDalvik.java b/support/src/test/java/tests/support/Support_ClassLoaderDalvik.java
new file mode 100644
index 0000000..17a4b13
--- /dev/null
+++ b/support/src/test/java/tests/support/Support_ClassLoaderDalvik.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package tests.support;
+
+import java.io.File;
+import java.net.URL;
+
+import dalvik.system.DexClassLoader;
+
+/**
+ * Implementation for Dalvik. Uses the DexClassLoader, so we can write
+ * temporary DEX files to a special directory. We don't want to spoil the
+ * system's DEX cache with our files. Also, we might not have write access
+ * to the system's DEX cache at all (which is the case when we're running
+ * CTS).
+ */
+class Support_ClassLoaderDalvik extends Support_ClassLoader {
+
+    private static File tmp;
+
+    static {
+        tmp = new File(System.getProperty("java.io.tmpdir"), "dex-cache");
+        tmp.mkdirs();
+    }
+
+    @Override
+    public ClassLoader getClassLoader(URL url, ClassLoader parent) {
+        return new DexClassLoader(url.getPath(), tmp.getAbsolutePath(),
+                null, parent);
+    }
+}
diff --git a/support/src/test/java/tests/support/Support_GetPutFields.java b/support/src/test/java/tests/support/Support_GetPutFields.java
index 3cf0d91..d4f49a6 100644
--- a/support/src/test/java/tests/support/Support_GetPutFields.java
+++ b/support/src/test/java/tests/support/Support_GetPutFields.java
@@ -79,7 +79,7 @@
         charValue = 'B';
         doubleValue = 424242.42;
         floatValue = 24.12f;
-        longValue = 6700654321l;
+        longValue = 6700654321L;
         intValue = 77777;
         objectValue = new SimpleClass(1965, "Hello Mars");
         shortValue = 1234;
diff --git a/support/src/test/java/tests/support/Support_GetPutFieldsDefaulted.java b/support/src/test/java/tests/support/Support_GetPutFieldsDefaulted.java
index 25b7417..a093134 100644
--- a/support/src/test/java/tests/support/Support_GetPutFieldsDefaulted.java
+++ b/support/src/test/java/tests/support/Support_GetPutFieldsDefaulted.java
@@ -90,7 +90,7 @@
         charValue = 'D';
         doubleValue = 523452.4532;
         floatValue = 298.54f;
-        longValue = 1234567890l;
+        longValue = 1234567890L;
         intValue = 999999;
         objectValue = new SimpleClass(1965, "Hello Jupiter");
         shortValue = 4321;
@@ -121,7 +121,7 @@
         charValue = getField.get("charValue", (char) 'D');
         doubleValue = getField.get("doubleValue", 523452.4532);
         floatValue = getField.get("floatValue", 298.54f);
-        longValue = getField.get("longValue", (long) 1234567890l);
+        longValue = getField.get("longValue", (long) 1234567890L);
         intValue = getField.get("intValue", 999999);
         objectValue = (Support_GetPutFieldsDefaulted.SimpleClass)
                        getField.get("objectValue",
diff --git a/support/src/test/java/tests/support/Support_GetPutFieldsDeprecated.java b/support/src/test/java/tests/support/Support_GetPutFieldsDeprecated.java
index 0f54e3e..19e9181 100644
--- a/support/src/test/java/tests/support/Support_GetPutFieldsDeprecated.java
+++ b/support/src/test/java/tests/support/Support_GetPutFieldsDeprecated.java
@@ -81,7 +81,7 @@
         charValue = 'A';
         doubleValue = 1231.342;
         floatValue = 43.22f;
-        longValue = 1560732321l;
+        longValue = 1560732321L;
         intValue = 33333;
         objectValue = new SimpleClass(2001, "A Space Odyssey");
         shortValue = 3078;
diff --git a/test-rules/src/main/java/libcore/junit/junit3/TestCaseWithRules.java b/test-rules/src/main/java/libcore/junit/junit3/TestCaseWithRules.java
new file mode 100644
index 0000000..b5acc82
--- /dev/null
+++ b/test-rules/src/main/java/libcore/junit/junit3/TestCaseWithRules.java
@@ -0,0 +1,112 @@
+/*
+ * 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.junit.junit3;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import org.junit.Rule;
+import org.junit.rules.MethodRule;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+import static org.junit.internal.runners.rules.RuleFieldValidator.RULE_VALIDATOR;
+
+/**
+ * A {@link TestCase} that supports the @Rule annotation from JUnit 4.
+ *
+ * <p>It supports both {@link TestRule} and {@link MethodRule} based rules when used with the
+ * {@code @Rule} annotation on public fields. The rules encapsulate the {@link TestCase#runBare()}
+ * method and so are run before the {@link TestCase#setUp()} and after the
+ * {@link TestCase#tearDown()} methods.
+ *
+ * <p>Classes that extend this must have a single no argument constructor.
+ */
+public abstract class TestCaseWithRules extends TestCase {
+
+    private final TestClass testClass;
+
+    private final List<Throwable> validationErrors;
+
+    public TestCaseWithRules() {
+        testClass = new TestClass(getClass());
+
+        validationErrors = new ArrayList<>();
+        RULE_VALIDATOR.validate(testClass, validationErrors);
+    }
+
+    @Override
+    public void runBare() throws Throwable {
+        if (!validationErrors.isEmpty()) {
+            throw new MultipleFailureException(validationErrors);
+        }
+
+        Statement statement = new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                superRunBare();
+            }
+        };
+
+        final String name = getName();
+        FrameworkMethod frameworkMethod;
+        try {
+            Method method = getClass().getMethod(name, (Class[]) null);
+            frameworkMethod = new FrameworkMethod(method);
+        } catch (NoSuchMethodException e) {
+            frameworkMethod = new FrameworkMethod(null) {
+                @Override
+                public String getName() {
+                    return name;
+                }
+
+                @Override
+                public Annotation[] getAnnotations() {
+                    return new Annotation[0];
+                }
+
+                @Override
+                public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+                    return null;
+                }
+            };
+        }
+        Description description =
+                Description.createTestDescription(getClass(), frameworkMethod.getName(),
+                        frameworkMethod.getAnnotations());
+
+        List<Object> rules = testClass.getAnnotatedFieldValues(this, Rule.class, Object.class);
+        for (Object rule : rules) {
+            if (rule instanceof TestRule) {
+                statement = ((TestRule) rule).apply(statement, description);
+            } else {
+                statement = ((MethodRule) rule).apply(statement, frameworkMethod, this);
+            }
+        }
+
+        statement.evaluate();
+    }
+
+    private void superRunBare() throws Throwable {
+        super.runBare();
+    }
+}
diff --git a/test-rules/src/main/java/libcore/junit/util/ResourceLeakageDetector.java b/test-rules/src/main/java/libcore/junit/util/ResourceLeakageDetector.java
new file mode 100644
index 0000000..dae7978
--- /dev/null
+++ b/test-rules/src/main/java/libcore/junit/util/ResourceLeakageDetector.java
@@ -0,0 +1,150 @@
+/*
+ * 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.junit.util;
+
+import java.lang.reflect.Method;
+import java.util.function.BiConsumer;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Provides support for testing classes that own resources which must not leak.
+ *
+ * <p><strong>This will not detect any resource leakages in OpenJDK</strong></p>
+ */
+public class ResourceLeakageDetector {
+    private static final LeakageDetectorRule LEAKAGE_DETECTOR_RULE;
+    private static final BiConsumer<Object, Integer> FINALIZER_CHECKER;
+
+    static {
+        LeakageDetectorRule leakageDetectorRule;
+        BiConsumer<Object, Integer> finalizerChecker;
+        try {
+            // Make sure that the CloseGuard class exists; this ensures that this is not
+            // running on a RI JVM.
+            Class.forName("dalvik.system.CloseGuard");
+
+            // Access the underlying support class using reflection in order to prevent any compile
+            // time dependencies on it so as to allow this to compile on OpenJDK.
+            Class<?> closeGuardSupportClass = Class.forName("dalvik.system.CloseGuardSupport");
+            Method method = closeGuardSupportClass.getMethod("getRule");
+            leakageDetectorRule = new LeakageDetectorRule((TestRule) method.invoke(null));
+
+            finalizerChecker = getFinalizerChecker(closeGuardSupportClass);
+
+        } catch (ReflectiveOperationException e) {
+            System.err.println("Resource leakage will not be detected; "
+                    + "this is expected in the reference implementation");
+            e.printStackTrace(System.err);
+
+            // Could not access the class for some reason so have a rule that does nothing and a
+            // finalizer checker that checks nothing. This should ensure that tests work properly
+            // on OpenJDK even though it does not support CloseGuard.
+            leakageDetectorRule = new LeakageDetectorRule(RuleChain.emptyRuleChain());
+            finalizerChecker = new BiConsumer<Object, Integer>() {
+                @Override
+                public void accept(Object o, Integer integer) {
+                    // Do nothing.
+                }
+            };
+        }
+
+        LEAKAGE_DETECTOR_RULE = leakageDetectorRule;
+        FINALIZER_CHECKER = finalizerChecker;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static BiConsumer<Object, Integer> getFinalizerChecker(Class<?> closeGuardSupportClass)
+            throws ReflectiveOperationException {
+        Method method = closeGuardSupportClass.getMethod("getFinalizerChecker");
+        return (BiConsumer<Object, Integer>) method.invoke(null);
+    }
+
+    /**
+     * @return the {@link LeakageDetectorRule}
+     */
+    public static LeakageDetectorRule getRule() {
+       return LEAKAGE_DETECTOR_RULE;
+    }
+
+    /**
+     * A {@link TestRule} that will fail a test if it detects any resources that were allocated
+     * during the test but were not released.
+     *
+     * <p>This only tracks resources that were allocated on the test thread, although it does not
+     * care what thread they were released on. This avoids flaky false positives where a background
+     * thread allocates a resource during a test but releases it after the test.
+     *
+     * <p>It is still possible to have a false positive in the case where the test causes a caching
+     * mechanism to open a resource and hold it open past the end of the test. In that case if there
+     * is no way to clear the cached data then it should be relatively simple to move the code that
+     * invokes the caching mechanism to outside the scope of this rule. i.e.
+     *
+     * <pre>{@code
+     *     @Rule
+     *     public final TestRule ruleChain = org.junit.rules.RuleChain
+     *         .outerRule(new ...invoke caching mechanism...)
+     *         .around(CloseGuardSupport.getRule());
+     * }</pre>
+     *
+     * @return a {@link TestRule} that detects resource leakages, or one that does nothing if
+     * resource leakage detection is not supported.
+     */
+    public static class LeakageDetectorRule implements TestRule {
+
+        private final TestRule leakageDetectorRule;
+
+        private LeakageDetectorRule(TestRule leakageDetectorRule) {
+            this.leakageDetectorRule = leakageDetectorRule;
+        }
+
+        @Override
+        public Statement apply(Statement base, Description description) {
+            return leakageDetectorRule.apply(base, description);
+        }
+
+        /**
+         * Ensure that when the supplied object is finalized that it detects the expected number of
+         * unreleased resources.
+         *
+         * <p>This helps ensure that classes which own resources protected using {@code CloseGuard}
+         * support leakage detection.
+         *
+         * <p>This must only be called from within the test currently being run otherwise it will
+         * fail if the resource leakage detected mechanism is disabled, e.g. in CTS.
+         *
+         * <p>Use as follows:
+         * <pre>
+         *     Object object = ...create and 'open' an object encapsulating a protected resource...;
+         *     // Check to make sure that the object reports a resource leak when it is finalized.
+         *     assertUnreleasedResourceCount(object, 1);
+         *
+         *     object = ... create, 'open' and then 'close' another object ...;
+         *     // Check to make sure that the object does not have any unreleased resources.
+         *     assertUnreleasedResourceCount(object, 0);
+         * </pre>
+         *
+         * @param owner the object that owns the resource and uses {@code CloseGuard} object to detect
+         * when the resource is not released.
+         * @param expectedCount the expected number of unreleased resources.
+         */
+        public void assertUnreleasedResourceCount(Object owner, int expectedCount) {
+            FINALIZER_CHECKER.accept(owner, expectedCount);
+        }
+    }
+}